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
    a2
    是32位整数
  • b
    b2
    是非零Java
    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

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

  • 如果两个运算具有相同的实数结果并使用相同的舍入规则,则它们具有相同的浮点结果
(有各种舍入规则。Java使用舍入到最近的ties到偶数,这意味着使用最近的可表示值,如果存在tie,则使用具有偶数低位的候选值。)

另一个后果是:

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

现在让我们考虑表达式<代码> 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
    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−0,它们比较相等但符号不同。

Summary 是,如果:

  • a
    a2
    是32位整数
  • b
    b2
    是非零Java
    double
    值,并且
  • a
    /
    b
    =
    a2
    /
    b2
然后
a/b
等于
a2/b2111 / 135.0 = 0.8222222222222222
333 / 405.0 = 0.8222222222222222