为什么System.out.println((long)Math.pow(2,63));
和System.out.println((long)(Math.pow(2,63)-1));
的输出在Java中相同?
答案 0 :(得分:9)
输出相同,因为double
没有足够的位来准确表示2 63 。
double
的
这为您提供最多17位十进制数字的精度。另一方面,您计算的值是9223372036854775808,因此需要准确表示19位数。结果,2 63 的实际表示是9223372036854776000:
1
的表示的尾数是相同的,而有效值为零的指数是1024,即两个数字的指数相差63,这大于尾数的大小。
当您的号码表示为double
时,会减1。由于minuend的大小远大于减数的大小,因此忽略整个减法运算。
在减去更大的数字之后你会得到相同的结果 - 一直到512,即2 9 (demo)。之后,指数的差异将小于52,因此您将开始得到不同的结果。
答案 1 :(得分:2)
use
会返回Math.pow( double, double )
个值。
double
是64位IEEE 754浮点。(https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)
如果你看这里:https://en.wikipedia.org/wiki/Double-precision_floating-point_format你会发现,这种格式包括:
double
返回的数字需要更高的精度(63)才能准确存储。
基本上,您添加的pow
低于此精度阈值。
相比之下,long具有64位精度。
为了使它更清楚,我们假设我们在十进制而不是在base2中工作:
在一些精度为1
的虚构小浮点数据类型中,值1000将存储为2
。如果添加1,则必须将其存储为1.001e3。但由于我们只有2的精度,它只能存储1.00e3
并且没有任何变化。所以1.00e3
在你的例子中也是如此,只是我们正在处理更大的数字和原因的基数。
答案 2 :(得分:0)
你应该使用括号来合并结果,然后减去1,如下所示:
System.out.println((long)Math.pow(2,63));
System.out.println(((long)(Math.pow(2,63))-1));
输出:
9223372036854775807
9223372036854775806
答案 3 :(得分:-1)
对于java中的长数据类型,最大值为9,223,372,036,854,775,807(含)。 (2 ^ 63 -1)
所以即使你尝试
System.out.println((long)Math.pow(2,65));
System.out.println((long)(Math.pow(2,63)-1));
输出
9223372036854775807
9223372036854775807