浮点错误会导致'a/(double)b >= a/b'失败吗?



result是否为假,因为4 / 2.0可能返回类似1.99999999的东西?比标题更普遍:

int a = // any valid int
int b = // any valid int
boolean result = (a/(double)b) >= a/b;

如果这是可能的,谁能提供一个ab的例子?如果这是不可能的,有任何java或浮点规范证明这一点吗?

我几分钟前写了这个逻辑,突然担心它会崩溃。我一直无法打破它,但我想知道它是否保证跨所有jvm。

如果abint的正值,则a/(double)b >= a/b .

我使用了以下前提,以及理解的语义,例如a/bint值将被转换为double,以便与>=的另一个操作数进行比较。

前提:

  • int的取值范围为[-2,147,483,648,2,147,483,648)。
  • double是IEEE 754 64位二进制文件。
  • 舍入模式为四舍五入。
  • 所有浮点运算,特别是除法,都符合IEEE 754。
  • 整数a/b向零截断。

标记:

  • aa的数学值。
  • bb的数学值。数学表达式,如a/b,是精确的,与计算表达式如a/b不同。
  • La/(double)b产生的值。
  • Ra/b产生的值。

证明:

  • 所有int的值都可以在double中表示,因此IEEE 754要求将int精确地转换为double
  • 因此,(double) a(double) b精确地产生aba/(double)b产生a/b,正确地四舍五入到最接近的double。自<<li> em> R <我> / b 截断向零,和<我> / b 是正的, R 是地板(<我> / b )。
  • 最大的a/b为2147483647/1 = 2147483647。这个数量级及以下的每个整数都可以精确地表示为double。L
  • double最近的<我> /<我> 。如果L通过舍入减少,它将减少到下一个低double。由于这个数量级的所有整数都是可表示的,所以floor(a/b)是可表示的,因此L至少是floor(a/b)。
  • 因此LR
  • Rdouble的转换是精确的,所以用>=比较LR的结果与数学上LR的结果相同。

对于负数,a = -10, b = 3失败

只要是正面输入,我想你是安全的。

设x为a除以b的实数结果

首先考虑x可以表示为int的情况。它也可以表示为双精度体,并且两次计算都返回x。

现在假设x不是int型。问题是x和a/(double b)之间舍入误差差的绝对值是否会超过a/b的截断误差。它不能。

截断误差t = x - a/b必须至少为1/b。x不能大于整数。所以t/x至少是1/Integer.MAX_VALUE/b。

4 / 2.0必须返回2.0,因为浮点除法是精确的。

负数可能会导致比较失败。注意-1/2 = 0-1.0/2.0 = -0.5 .

最新更新