Java:Math.pow返回令人困惑的结果

时间:2017-09-28 19:05:38

标签: java

我正在研究Java中的Math.pow()函数,但下面的代码分别给出了不同的结果。

案例1:

BigDecimal divisor = new BigDecimal(Math.pow(10,9)+7);
BigDecimal dividend = new BigDecimal(1000000000543543509L);
System.out.println(dividend.remainder(divisor)); // 543543558

案例2:

System.out.println((1000000000543543509L%((int)Math.pow(10,9)+7))+""); 
//543543558

案例3:

System.out.println((1000000000543543509L%(Math.pow(10,9)+7))+""); //5.43543601E8

为什么我在案例2和案例3中获得了不同的结果,但案例1和案例2中的结果相同? 以上哪种情况最准确?

1 个答案:

答案 0 :(得分:1)

在前两种情况下,long的值保留了long的所有精度。在第三种情况下,long被强制转换为double,并且一些精度会丢失。请注意,pow返回一个double,而double + int会将int强制转换为double。类似地,long%double会导致long被强制转换为double。

我们可以通过明确地执行演员来证明结果:

System.out.println((long)((double)1000000000543543509L));
#1000000000543543552

您可以使用modulo验证值是什么操作。

System.out.println(1000000000543543552L%((int)(Math.pow(10, 9) + 7)));
#543543601

所以问题不是战争,而是长期不适合双倍。

更一般地说,如果我们在Widening Primitive Conversion上咨询jls,我们可以看到long可以在没有显式强制转换的情况下被提升为double(或float)。这是因为它不会丢失任何幅度信息。尽管如此示例所示,但您可能会失去一些精确度。

相关问题