2个相同比例的数字相除结果总是相同的吗?

Will division result of 2 numbers with the same ratio always be the same?

a 是一个 integer.
b 也是一个 integer,但声明为 double
c = a/b,并且 c 也声明为 double

还有a2b2c2,规则与abc相似。
另外,在十进制代数方面,2组数满足:a / b = a2 / b2(如8 / 18.0 = 12 / 27.0

问题是:

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


@更新

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

(顺便说一句,这个问题在编写测试用例时出现,不确定简单地使用 == 是否足够,或者允许使用小的增量(= (expected - actual) / actual),例如 +/- 0.000001 ).

总结

是,如果:

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

然后 a / b 等于 a2 / b2。 (注意 a / b 表示实数运算,而 a / b 表示浮点运算。 4 / 3 正好是 1⅓,而 4./3 是 1.3333333333333332593184650249895639717578887939453125。)

证明

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

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

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

(有各种舍入规则。Java 使用 round-to-nearest-ties-to-even,意思是使用最接近的可表示值,如果有平局,则与使用偶数低位。)

另一个结果是:

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

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

接下来是除法,a / ba2 / b2。我们被告知 a / b = a2 / b2。这告诉我们 a / b 的实数结果等于 a2 / b2 的实数结果。由于这两个运算的实数结果相同,使用相同的舍入规则,所以它们的浮点数结果相同。

讨论

以上的一些限制是:

  • 如果 aa2 可能超过 53 位,则它可能具有无法在 double 中表示的值。那么将其转换为double的操作就得对其取整了。四舍五入可能会以不同方式影响 aa2,然后商 a / ba2 / b2 可能会不同。
  • 一些编程语言对如何执行浮点运算并不严格,并且它们不符合 IEEE-754 规则。我相信以上内容适用于 Java,但 C 或 C++ 中可能存在问题。

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

如果 aa2bb2 为零,则两个运算都会产生 NaN,但两个 NaN 不会比较相等。

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