我可以将一个数字存储为HBase中的Long和Double。它们都在Java中占用8个字节。
使用Double的优点在于它为存储整数提供了更广泛的范围。
然而,我认为Long的范围也足以供我使用。
有没有人对Long vs Dobule的序列化和反序列化性能有任何想法?我对它们之间的比较感兴趣。
感谢。
答案 0 :(得分:18)
如果要存储整数,请使用Long
。您声明“使用Double的优点是它为存储整数提供了更广泛的范围”是不正确的。两者都是64位长,但double
必须使用一些位作为指数,留下更少的位来表示幅度。您可以在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
请注意
另一种说法是long
精度不到19位,而double
精度只有16位。 Double可以存储大于16位的数字,但代价是以低位数字截断/舍入。
如果您需要超过19位数的精确度,您必须使用BigInteger
,预期性能会下降。
答案 1 :(得分:3)
这看起来像是错误的战斗:
长数据类型是64位带符号的二进制补码整数。它有 最小值为-9,223,372,036,854,775,808,最大值为 9,223,372,036,854,775,807(含)。
这非常接近19位有效数字
这给出了15到17个有效小数位数。
所以,尽管它有明显的“优势”,Double会让你比Long更糟糕。我只是在这里猜测,但直观地说,我认为浮点类型的序列化/反序列化比对整数数据类型的相同操作更昂贵,但即使存在差异,它们在现代系统上也会非常小。
因此,在使用整数时,请坚持使用Long。
答案 2 :(得分:1)
在没有具体了解的情况下,我会想象long
和double
都具有相同的序列化:取64位并将它们放在线上。同样地,我认为反序列化只需要从线路上取64位,并声明它们现在代表long
或double
。任何64位都将代表有效的long
或double
(虽然并非所有都代表有限的双倍),因此没有任何验证或额外的工作。