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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有相同比率的2个数的除法结果总是相同吗?相关的知识,希望对你有一定的参考价值。

a是一个integerb也是integer,但被宣布为doublec = 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)。

答案

摘要

是的,如果:

  • 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,那么这两个操作都会产生无穷大。符号将是分子和除数符号的异或。这意味着a / ba2 / b2可以产生不同的无穷大(一个正,一个负),即使a = a2b = b2,因为IEEE-754同时具有+0和-0,它们相等但具有不同的符号。

以上是关于具有相同比率的2个数的除法结果总是相同吗?的主要内容,如果未能解决你的问题,请参考以下文章

IEEE 754浮点除法或减法本身是不是总是产生相同的值?

在具有相同上下文的2个对象上调用JSON.stringify(obj)是否总是获得相同的字符串?

插入/更新后跟选择(nolock)是不是会产生具有相同数据的意外结果?

这两个postgres表达式会给出相同的结果吗?

如何从相同的数据构造2列并计算比率?

当结果具有相同分数时在 Elasticsearch 中分页