9

我可以在 HBase 中将数字存储为 Long 和 Double。在 Java 中,它们都占用 8 个字节。

使用 Double 的优点是它为存储整数提供了更广泛的范围。

但是,我认为 Long 的范围也足以供我使用。

有人对 Long vs Dobule 的序列化和反序列化性能有任何想法吗?我对它们之间的比较感兴趣。

谢谢。

4

3 回答 3

25

如果要存储整数,请使用Long. 您关于“使用 Double 的优势在于它为存储整数提供了更广泛的范围”的说法是不正确的。两者都是 64 位长,但double必须使用一些位作为指数,留下更少的位来表示幅度。您可以在 a 中存储更大的数字,double但会丢失精度。

换句话说,对于大于某个上限的数字,您不能再存储相邻的“整数”......给定一个高于此阈值的整数值,“下一个”可能double会比前一个数字大 1 以上。

例如

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);
    }

}

这输出:

9223372036854775707 9223372036854775708
9223372036854776000.000000 9223372036854776000.000000 9223372036854778000.000000

注意

  1. Long.MAX_VALUE-100 的双重表示等于原始值
  2. Long.MAX_VALUE-100 的双重表示加 1 无效
  3. 在这个量级上,一个双精度值和下一个可能的双精度值之间的差值为 2000。

另一种说法是它的long精度不到 19 位,而精度double只有 16 位。Double 可以存储大于 16 位的数字,但代价是对低位数字进行截断/舍入。

如果您需要超过 19 位的精度,BigInteger则必须使用 ,预期性能会下降。

于 2012-10-02T22:08:10.967 回答
3

这看起来像是一场错误的战斗:

来自Java 教程

long 数据类型是一个 64 位有符号二进制补码整数。它的最小值为-9,223,372,036,854,775,808,最大值为9,223,372,036,854,775,807(含)。

这非常接近 19 位有效数字

来自维基百科

这给出了 15 - 17 位有效十进制数字的精度。

所以,尽管它明显的“优势” Double 将比 Long 为您提供更差的服务。我只是在这里猜测,但直觉上我会说浮点类型的序列化/反序列化是比整数数据类型的相同操作更昂贵的操作,但即使存在差异,它们在现代系统上也会非常小。

因此,在处理整数时,请坚持使用 Long。

于 2012-10-02T22:13:20.387 回答
2

在不知道具体情况的情况下,我会想象 along和 adouble都具有相同的序列化:获取 64 位并将它们放在网络上。同样,我想反序列化只是从线路上取下 64 位并声明它们现在代表 a longor的问题double。任何 64 位都将代表一个有效的longdouble(尽管不是所有的都代表一个有限的双精度),所以没有任何验证或额外的工作。

于 2012-10-02T22:24:58.527 回答