具有相同比率的2个数字的除法结果是否总是相同?

时间:2019-04-21 11:33:15

标签: floating-point binary division

ainteger
b也是integer,但声明为double
c = a/bc也被声明为double

此外,还有a2b2c2,其规则与abc类似。
另外,根据十进制代数,两组数字满足:a / b = a2 / b2(例如8 / 18.0 = 12 / 27.0

问题是:

  • 在计算机(二进制文件)中,cc2会始终完全相同吗?
    例如
    111 / 135.0 = 0.8222222222222222
    333 / 405.0 = 0.8222222222222222
    

(我的猜测是肯定的,因为所有整数都可以用有限的位数表示为二进制,但不能完全确定计算机除法是否会有所不同。)


@Update

假设计算机/语言使用32位表示整数,使用64位表示双精度。

(顺便说一句,在编写测试用例时会遇到此问题,不确定仅使用==就足够了,还是允许使用较小的增量(= (expected - actual) / actual),例如+/- 0.000001)。

1 个答案:

答案 0 :(得分:4)

摘要

是,如果:

  • aa2是32位整数,
  • bb2是非零的Java double值,并且
  • a / b = a2 / b2

然后a / b等于a2 / b2。 (请注意,a / b表示实数算术,而a / b表示浮点算术。4 / 3正好是1⅓,而{{ 1}}是1.3333333333333332593184650249895639717578578939939453125。)

证明

根据作者的评论,这是针对Java的,它使用IEEE 754,其中包括4./3的IEEE-754基本64位二进制浮点数。

大多数浮点运算的基本属性是计算结果是四舍五入到浮点格式可表示的最接近值的实数结果。其结果是:

  • 如果两个运算具有相同的实数结果,并使用相同的舍入规则,则它们具有相同的浮点结果。

(有各种舍入规则。Java使用从最接近的四舍五入关系到四舍五入关系,这意味着使用了最接近的可表示值,如果存在平局,则使用具有低位偶数的候选值)

另一个后果是:

  • 如果操作的实数结果可以浮点格式表示,则为浮点结果。 (没有舍入错误。)

现在让我们考虑表达式doublea / b。由于类型不同,每个步骤的第一步是将a2 / b2a分别从其整数类型转换为a2。这个问题告诉我们假设整数类型具有32位。所有32位整数都可以在double中精确表示(因为double具有53位有效数字)。转换值的数学结果当然是值本身,因为转换旨在更改类型,而不是值。因此,将doublea转换为a2的结果分别恰好是doublea

接下来,有一个分隔a2a / b。我们被告知a2 / b2 / a = b / a2。这告诉我们b2的实数结果等于a / b的实数结果。由于这两个运算具有相同的实数结果,并且使用相同的舍入规则,因此它们的浮点结果是相同的。

讨论

上述限制包括:

  • 如果a2 / b2a可能超过53位,则其值可能无法在a2中表示。然后,将其转换为double的操作将需要四舍五入。四舍五入可能会对doublea产生不同的影响,然后商a2a / b可能会不同。
  • 某些编程语言对如何执行浮点运算并不严格,并且它们不符合IEEE-754规则。我相信以上内容适用于Java,但是C或C ++可能存在问题。

请注意,a2 / b2b可能很小(包括零),导致商溢出,并且计算结果为无穷大。尽管如此,b2 / a = b / a2的事实将要求两个结果都是无穷大或都不是-浮点结果等于实数的规则数字结果相等仍然成立。

如果b2aa2b为零,则两个操作都将产生NaN,但两个NaN将不相等。

如果b2a不为零,而a2b为零,则两个操作都将产生无穷大。该符号将是分子和除数的符号的XOR。这意味着即使b2 = a / ba2 / b2 = aa2b也会产生不同的无穷大(一个正,一个负)。 ,因为IEEE-754的+0和-0都相等,但符号不同。