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

Java:Math.pow返回令人困惑的结果,java,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.print

我正在研究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中得到相同的结果?
上述哪种情况最准确?

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

我们可以通过显式执行强制转换来演示结果:

System.out.println((long)((double)1000000000543543509L));
#1000000000543543552
您可以使用模来验证op得到的值

System.out.println(1000000000543543552L%((int)(Math.pow(10, 9) + 7)));
#543543601
所以问题不是pow,而是不适合双打的长距离


更一般地说,如果我们咨询jls,我们可以看到long可以升级为double(或float),而无需显式强制转换。这是因为它不会丢失任何震级信息。虽然,如本例所示,您可能会失去一些精度。

当您执行
长a
双b
时,您认为可能会发生重复的情况,计算
a%b
?b被视为long,还是a被视为double?@nullpointer问题似乎是转换为double的大long。