如果没有余数,双重除法是否等同于整数除法?

5

在JVM上,两个double值之间的除法是否总是产生与执行整数除法相同的精确结果?

前提条件如下:

  • 没有余数的除法
  • 不会被零除
  • 变量 xy 实际上包含整数值。

例如,在以下代码中:

double x = ...;
int resultInt = ...;
double y = x * resultInt;
double resultDouble = y / x; // double division

resultDouble 总是等于 resultInt 吗?还是会有一些精度损失?


只有40亿个32位整数。你可以通过枚举所有值来测试它。 - the8472
3个回答

4
有两个原因会导致将int分配给double或float可能会失去精度:
  • 有些数字无法表示为double/float,因此它们最终被近似
  • 大的整数数字可能在其最不显著的位中包含过多的精度
因此,这取决于int的大小,在Java中,double使用52位尾数,因此能够表示32位整数而不会丢失数据。
这两个站点都有很棒的例子:

1- Java的浮点(不)精度

2-关于Java中的原始数据类型

还请查看:

精度损失--int-> float or double


3

如果 xy 都在 int 范围内,那么除非除法是 -2147483648.0 / -1.0,否则结果会是一个 double,而不是 int

如果除数和被除数都在 int 范围内,它们可以精确地表示为 double。如果它们的比值是一个整数,并且除法不是 -2147483648.0 / -1.0,那么比值也在 int 范围内,可以精确地表示为 double。该 double 是离结果最近的值,因此必须是 double 除法的结果。

如果 xy 是超出 int 范围的整数,上述推理不一定适用。


你的陈述并不总是正确的:-2147483648.0 / -1.0 != -2147483648 / -1 - apangin

3

这个说法是正确的,但当被除数为 Integer.MIN_VALUE 时,两个整数相除可能会超出整数范围。

    int n = Integer.MIN_VALUE;
    int m = -1;
    System.out.println(n / m);                          // -2147483648
    System.out.println((int) ((double)n / (double)m));  // 2147483647

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接