具有相同比率的2个数的除法结果总是相同吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有相同比率的2个数的除法结果总是相同吗?相关的知识,希望对你有一定的参考价值。
a
是一个integer
。
b
也是integer
,但被宣布为double
。
c = a/b
和c
也被宣布为double
。
并且,有a2
,b2
,c2
,与a
,b
,c
具有相似的规则。
此外,就十进制代数而言,这两组数字满足:a / b = a2 / b2
,(例如8 / 18.0 = 12 / 27.0
)。
问题是:
- 在计算机(二进制)中,
c
和c2
总是完全相同吗? 例如111 / 135.0 = 0.8222222222222222 333 / 405.0 = 0.8222222222222222
(我的猜测是肯定的,因为所有整数都可以用有限数字的二进制表示,但是当涉及计算机中的除法时,不完全肯定会有所不同。)
@Update
假设计算机/语言使用32位表示整数,64位表示双精度。
(顺便说一下,这个问题在写一个测试用例时就会出现,不确定只使用==
就足够了,或者允许使用小三角洲(= (expected - actual) / actual
),例如+/- 0.000001
)。
摘要
是的,如果:
a
和a2
是32位整数,b
和b2
是非零Javadouble
值,并且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 / b
和a2 / b2
。由于混合类型,每个中的第一步是分别将a
或a2
从其整数类型转换为double
。问题告诉我们假设整数类型有32位。所有32位整数都可以在double
中完全表示(因为double
具有53位有效数字)。转换值的数学结果当然是值本身,因为转换旨在改变类型而不是值。因此,将a
或a2
转换为double
的结果分别恰好是a
或a2
。
接下来,有分裂,a / b
或a2 / b2
。我们被告知a
/ b
= a2
/ b2
。这告诉我们a / b
的实数结果等于a2 / b2
的实数结果。由于这两个操作具有相同的实数结果并使用相同的舍入规则,因此它们的浮点结果是相同的。
讨论
以上的一些限制是:
- 如果
a
或a2
可能超过53位,它可能具有double
中无法表示的值。然后将它转换为double
的操作将不得不围绕它。舍入可能会不同地影响a
和a2
,然后商a / b
和a2 / b2
可能会有所不同。 - 一些编程语言对于如何执行浮点运算并不严格,并且它们不符合IEEE-754规则。我相信上述内容适用于Java,但在C或C ++中可能存在问题。
请注意,b
和b2
可能非常小(包括零),因此商会溢出,计算结果为无穷大。尽管如此,a
/ b
= a2
/ b2
的事实要求两个结果都是无穷大或两者都不是 - 相等实数结果的浮点结果相等的规则仍然成立。
如果a
,a2
,b
和b2
为零,则两个操作都将产生NaN,但两个NaN不会相等。
如果a
和a2
不是零但是b
和b2
,那么这两个操作都会产生无穷大。符号将是分子和除数符号的异或。这意味着a / b
和a2 / b2
可以产生不同的无穷大(一个正,一个负),即使a
= a2
和b
= b2
,因为IEEE-754同时具有+0和-0,它们相等但具有不同的符号。
以上是关于具有相同比率的2个数的除法结果总是相同吗?的主要内容,如果未能解决你的问题,请参考以下文章
在具有相同上下文的2个对象上调用JSON.stringify(obj)是否总是获得相同的字符串?