Double vs Long Serialization in Java

I can store a number as a Long and Double in HBase. Both of them takes 8 bytes in Java.

Advantage of Using Double is that it gives a more wider range for storing Whole Numbers.

However, i think range of Long is also enough for my use.

Does anyone has any idea about the serialization and de-serialization performance of Long vs Dobule? I am interested in comparison between them.

Thanks.

1

3 Answers

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

  1. The double representation of Long.MAX_VALUE-100 does NOT equal the original value
  2. Adding 1 to the double representation of Long.MAX_VALUE-100 has no effect
  3. 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.

9

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.

1

Without knowing specifically, I would imagine that both a long and a double have the same serialization: take the 64 bits and put them on the wire. Similarly, I'd imagine that deserialization is just a matter of taking 64 bits off the wire and declaring that they now represent a long or double. Any 64 bits are going to represent a valid long or double (though not all will represent a finite double), so there isn't any validation or extra work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest