double 的模数结果不正确

Incorrect modulo result with double

我的代码如下(Java):

long num = 988530483551494950L;
int r1 = (int) (num % (Math.pow(10, 9) + 7));
int r2 = (int) (num % 1000000007);
System.out.println(r1); // 631781580
System.out.println(r2); // 631781618

r1r2应该是一样的,但是不一样,为什么?是因为Math.pow(10, 9) + 7是一个double吗?如果是这样,为什么 double 类型会导致问题? double不是小数,结果不应该一致吗?

当您将 %longdouble 操作数一起使用时,将应用数字提升。 long转换为double,然后取余

但是,double 不能精确表示值 988530483551494950。最接近的表示表示值 988530483551494912(参见 conversion here)。

事实上,988530483551494912 除以 10000000007 的余数是 631781580 - 您得到的“错误”答案。

% 运算符对整数和小数的处理方式不同。在您的代码中,r2 是整数运算符的结果,r1 是小数运算符的结果(Math#pow 的结果是 double)。如果你想要r1 == r2,那么:

  • 将 num 设为 double 类型。
  • 将 Math.pow(10, 9) + 7 转换为 int 或 long
  • 1000000007 设为双精度类型 (1000000007d)

(使用这些解决方案中的 一个

希望对你有所帮助。