long与double在java中本身都是用64位存储的,本来用的比较简单, 并没有太在意一些细节,大抵就是一个存整数,一个存浮点数。
顺着HBase的一个问题,查了一下stackoverflow,发现了一些比较有意思的事情。
long存的是连续的整数,而对于double,当数很大的时候,它所能表示两个相邻数之间的间隔就会比较大,比如long可以存9223372036854775707和9223372036854775708,而double是无法区分这两个数的。例如:
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由于有exp位,可以存16位以上的数字,但是需要以低位的不精确作为代价。如果需要高于19位数字的精确存储,则必须用BigInteger来保存,当然会牺牲一些性能。