I’ve tried looking for definitive answers but the only difference I see seems to be based on the precision of the numbers?
Which data type is larger and which one is smaller?
performance - double vs long serialization in java - Stack Overflow
What the difference between double and long data types
java - Confused with size of long and double - Stack Overflow
numbers - Confusing long vs double behavior in Java - Stack Overflow
Videos
If you are storing integers, use Long. Your statement that "Advantage of Using Double is that it gives a more wider range for storing Whole Numbers" is incorrect. Both are 64 bits long, but double has to use some bits for the exponent, leaving fewer bits to represent the magnitude. You can store larger numbers in a double but you will lose precision.
In other words, for numbers larger than some upper bound you can no longer store adjacent "whole numbers"... given an integer value above this threshold, the "next" possible double will be more than 1 greater than the previous number.
For example
public class Test1
{
public static void main(String[] args) throws Exception
{
long long1 = Long.MAX_VALUE - 100L;
double dbl1 = long1;
long long2 = long1+1;
double dbl2 = dbl1+1;
double dbl3 = dbl2+Math.ulp(dbl2);
System.out.printf("%d %d\n%f %f %f", long1, long2, dbl1, dbl2, dbl3);
}
}
This outputs:
9223372036854775707 9223372036854775708
9223372036854776000.000000 9223372036854776000.000000 9223372036854778000.000000
Note that
- The double representation of Long.MAX_VALUE-100 does NOT equal the original value
- Adding 1 to the double representation of Long.MAX_VALUE-100 has no effect
- At this magnitude, the difference between one double and the next possible double value is 2000.
Another way of saying this is that long has just under 19 digits precision, while double has only 16 digits precision. Double can store numbers larger than 16 digits, but at the cost of truncation/rounding in the low-order digits.
If you need more than 19 digits precision you must resort to BigInteger, with the expected decrease in performance.
This looks like the wrong battle:
From the Java Tutorial
The long data type is a 64-bit signed two's complement integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive).
That's pretty close to 19 significant digits
From Wikipedia
This gives from 15 - 17 significant decimal digits precision.
So, despite its apparent "superiority" Double will serve you worse than Long. And I'm merely guessing here, but intuitively I'd say serialization/deserialization of floating point types are costlier operations than the same operations on integral data types, but even if there are differences they will be quite small on modern systems.
So, when working with integers, stick to Long.
The absolute quantity of information that you can store in 64 bit is of course the same.
What changes is the meaning you assign to the bits.
In an integer or long variable, the codification used is the same you use for decimal numbers in your normal life, with the exception of the fact that number two complement is used, but this doesn't change that much, since it's only a trick to gain an additional number (while storing just one zero instead that a positive and a negative).
In a float or double variable, bits are split in two kinds: the mantissa and the exponent. This means that every double number is shaped like XXXXYYYYY where it's numerical value is something like XXXX*2^YYYY. Basically you decide to encode them in a different way, what you obtain is that you have the same amount of values but they are distribuited in a different way over the whole set of real numbers.
The fact that the largest/smallest value of a floating number is larger/smaller of the largest/smalles value of a integer number doesn't imply anything on the amount of data effectively stored.
A double can store a larger number by having larger intervals between the numbers it can store, essentially. Not every integer in the range of a double is representable by that double.
More specifically, a double has one bit (S) to store sign, 11 bits to store an exponent E, and 52 bits of precision, in what is called the mantissa (M).
For most numbers (There are some special cases), a double stores the number (-1)^S * (1 + (M * 2^{-52})) * 2^{E - 1023}, and as such, when E is large, changing M by one will make a much larger change in the size of the resulting number than one. These large gaps are what give doubles a larger range than longs.
Though not a replacement, you can use java.lang.math.BigDecimal.You can roughly store billion of digits until you run out of memory. Its an arbitrary precision class, it will get as large as you'd like until your computer runs out of memory.
As per the documentation of BigDecimal:
Immutable, arbitrary-precision signed decimal numbers. A BigDecimal consists of an arbitrary precision integer unscaled value and a non-negative 32-bit integer scale, which represents the number of digits to the right of the decimal point. The number represented by the BigDecimal is (unscaledValue/10scale). BigDecimal provides operations for basic arithmetic, scale manipulation, comparison, hashing, and format conversion.
There is no straight replacement in Java.
You can use BigDecimal for this purpose.
You should understand that the bigger your double value is, the bigger lost of precision you will receive using it in your mathematical operations. BigDecimal helps you to aware this problem.
Here is code sample with BigDecimal:
String decimalString = "1423545135143513.523";
BigDecimal decimal = new BigDecimal(decimalString);
By this link you can find many examples with usage of BigDecimal class.