Пав*_*вел 1 java floating-point double floor
它可能是在深夜,但我无法理解这段代码的行为:
public class DT {
static void theTest(double d){
double e = Math.floor(d/1630)*1630;
System.out.println(e-d);
}
public static void main(String[] args) {
theTest(2*1630);
theTest(2*1631);
theTest(2*1629);
theTest(8.989779443802325E18);
}
Run Code Online (Sandbox Code Playgroud)
}
在我的undertangind中,所有4个案例都应该是非正面的,即"e"总是<="d",但我得到以下输出:
0.0
-2.0
-1628.0
1024.0
Run Code Online (Sandbox Code Playgroud)
为什么??.因为这与FastMath相同,我怀疑是双重特定的?但有人可以解释我这个吗?
当你获得大量数据时,双打的间隔比整数更宽.在此范围内进行除法时,可以向上或向下舍入结果.所以在你的第四个测试用例中,除法的结果d/1630实际上是四舍五入到最接近的可用双精度.由于这是一个整数,所以调用floor不会改变它.1630然后将它乘以得到的结果大于d.
编辑
这个效果在2 ^ 52时开始.一旦你超过2 ^ 52,就没有更多的非整数双打.在2 ^ 52和2 ^ 53之间,双精度只是整数.在2 ^ 53以上,双精度比整数间隔更宽.
问题中划分的结果5515202112762162.576... 是在2 ^ 52和2 ^ 53之间.它四舍五入到最接近的double,它与最接近的整数相同,即5515202112762163.现在,floor不会更改此数字,乘以1630得到的结果大于d.
总而言之,我猜这个答案的第一句话有点误导 - 你不需要双倍的间隔比这个效果的整数更广泛; 你只需要它们至少与整数一样宽.
如果值d介于0和2 ^ 52*1630之间,则问题中的程序将永远不会输出正数.
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |