我可以在 HBase 中将数字存储为 Long 和 Double。在 Java 中,它们都占用 8 个字节。
使用 Double 的优点是它为存储整数提供了更广泛的范围。
但是,我认为 Long 的范围也足以供我使用。
有人对 Long vs Dobule 的序列化和反序列化性能有任何想法吗?我对它们之间的比较感兴趣。
谢谢。
我可以在 HBase 中将数字存储为 Long 和 Double。在 Java 中,它们都占用 8 个字节。
使用 Double 的优点是它为存储整数提供了更广泛的范围。
但是,我认为 Long 的范围也足以供我使用。
有人对 Long vs Dobule 的序列化和反序列化性能有任何想法吗?我对它们之间的比较感兴趣。
谢谢。
如果要存储整数,请使用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
注意
另一种说法是它的long
精度不到 19 位,而精度double
只有 16 位。Double 可以存储大于 16 位的数字,但代价是对低位数字进行截断/舍入。
如果您需要超过 19 位的精度,BigInteger
则必须使用 ,预期性能会下降。
这看起来像是一场错误的战斗:
来自Java 教程
long 数据类型是一个 64 位有符号二进制补码整数。它的最小值为-9,223,372,036,854,775,808,最大值为9,223,372,036,854,775,807(含)。
这非常接近 19 位有效数字
来自维基百科
这给出了 15 - 17 位有效十进制数字的精度。
所以,尽管它明显的“优势” Double 将比 Long 为您提供更差的服务。我只是在这里猜测,但直觉上我会说浮点类型的序列化/反序列化是比整数数据类型的相同操作更昂贵的操作,但即使存在差异,它们在现代系统上也会非常小。
因此,在处理整数时,请坚持使用 Long。
在不知道具体情况的情况下,我会想象 along
和 adouble
都具有相同的序列化:获取 64 位并将它们放在网络上。同样,我想反序列化只是从线路上取下 64 位并声明它们现在代表 a long
or的问题double
。任何 64 位都将代表一个有效的long
或double
(尽管不是所有的都代表一个有限的双精度),所以没有任何验证或额外的工作。