Floating point 两个具有相同比率的数字的除法结果是否总是相同的?
Floating point 两个具有相同比率的数字的除法结果是否总是相同的?,floating-point,binary,division,Floating Point,Binary,Division,a是一个整数 b也是一个整数,但声明为double c=a/b,c也被声明为double 还有a2,b2,c2,规则类似于a,b,c 此外,就十进制代数而言,两组数字满足:a/b=a2/b2,(例如8/18.0=12/27.0) 问题是: 在计算机(binary)中,c和c2是否总是完全相同? 例如 (我的猜测是肯定的,因为所有整数都可以用有限位数的二进制表示,但不能完全确定在计算机除法方面会有什么不同。) @更新 假设计算机/语言使用32位表示整数,64位表示双精度 (顺便说一句,在编
a
是一个整数
b
也是一个整数
,但声明为double
c=a/b
,c
也被声明为double
还有a2
,b2
,c2
,规则类似于a
,b
,c
此外,就十进制代数而言,两组数字满足:
a/b=a2/b2
,(例如8/18.0=12/27.0
)
问题是:
- 在计算机(binary)中,
和c
是否总是完全相同?c2
例如
@更新 假设计算机/语言使用32位表示整数,64位表示双精度 (顺便说一句,在编写测试用例时,这个问题会出现,不确定简单地使用
=
是否足够,或者允许一个小的增量(=(预期-实际)/实际
),例如+/-0.000001
)。总结
是,如果:
和a
是32位整数a2
和b
是非零Javab2
值,并且double
/a
=b
/a2
b2
a/b
等于a2/b2
。(请注意,a
/b
表示实数算术,而a/b
表示浮点算术。4
/3
正好是1。)⅓, 而4./3
为1.33333325931846502499895639717578887939453125。)
证明
根据作者的评论,这是针对Java的,它使用IEEE 754,包括IEEE-754基本64位二进制浮点,用于double
大多数浮点运算的一个基本特性是,计算结果是实数结果,四舍五入到以浮点格式表示的最接近的值。其结果是:
- 如果两个运算具有相同的实数结果并使用相同的舍入规则,则它们具有相同的浮点结果
- 如果运算的实数结果可以用浮点格式表示,则为浮点结果。(没有舍入误差。)
现在让我们考虑表达式<代码> A/B < /代码>和<代码> A2/B2< /代码>。由于混合类型,每个步骤的第一步是将
a
或a2
分别从其整数类型转换为双
。这个问题告诉我们假设整数类型有32位。所有32位整数都可以在double
中精确表示(因为double
有53位有效位)。转换值的数学结果当然是值本身,因为转换旨在更改类型,而不是值。因此,将a
或a2
转换为double
的结果分别是a
或a2
接下来是分区,a/b
或a2/b2
。我们被告知a
/b
=a2
/b2
。这告诉我们,a/b
的实数结果等于a2/b2
的实数结果。由于这两个操作具有相同的实数结果并使用相同的舍入规则,因此它们的浮点结果是相同的
讨论
上述限制包括:
- 如果
或a
可能超过53位,则其值可能无法在a2
中表示。然后,将其转换为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−0,它们比较相等但符号不同。Summary
是,如果:
和a
是32位整数a2
和b
是非零Javab2
值,并且double
/a
=b
/a2
b2
a/b
等于a2/b2111 / 135.0 = 0.8222222222222222
333 / 405.0 = 0.8222222222222222