我觉得这很有趣:
System.out.println( (long)(Math.pow(2,63) - 1) == Long.MAX_VALUE); // true
System.out.println( (long)(Math.pow(2,63) - 5) == Long.MAX_VALUE); // true
System.out.println( (long)(Math.pow(2,63) - 512) == Long.MAX_VALUE); // true
System.out.println( (long)(Math.pow(2,63) - 513) == Long.MAX_VALUE); // false
Run Code Online (Sandbox Code Playgroud)
最后三行应该打印false,但实际上只有最后一行,我减去的513给出了正确的答案.
为什么512/513是不准确的突破点?我可以做的唯一连接是512是一千字节的一半.
我知道造成这种情况的原因是由于返回a 而产生的double不准确性Math.pow(int, int)double
我试过这个,java.math.BigInteger这就是我得到的:
BigInteger b = new BigInteger("2");
System.out.println( (b.pow(63).longValue() - 1) == Long.MAX_VALUE ); // true
System.out.println( (b.pow(63).longValue() - 5) == Long.MAX_VALUE ); // false
System.out.println( (b.pow(63).longValue() - 512) == Long.MAX_VALUE ); // false
System.out.println( (b.pow(63).longValue() - 513) == Long.MAX_VALUE ); // false
Run Code Online (Sandbox Code Playgroud)
这是浮点舍入的问题.double实际上有53位有效数,因此在2 ^ 63范围内,连续的双精度数除以1024. 512是你可以减去并且仍然向上舍入的最多.减去513超过下一个双下降的一半,然后向下舍入.
该计划证明了这个问题:
import java.math.BigDecimal;
public class Test
{
public static void main(String[] args) {
double maxValue = (double)Long.MAX_VALUE;
System.out.println(new BigDecimal(maxValue));
double nextDown = Math.nextAfter(maxValue, 0);
System.out.println(new BigDecimal(nextDown));
System.out.println(maxValue-nextDown);
}
}
Run Code Online (Sandbox Code Playgroud)
它打印:
9223372036854775808
9223372036854774784
1024.0
Run Code Online (Sandbox Code Playgroud)
显示在Long.MAX_VALUE的双倍当量和零方向的下一个双精度之间的1024间隙.
| 归档时间: |
|
| 查看次数: |
1949 次 |
| 最近记录: |