假设t
,a
,b
都是双(IEEE Std 754)变量,a
,b
的值均为{ {1}}(但可能是NaN
)。
在Inf
之后,我是否必须拥有t = a - b
?
答案 0 :(得分:25)
绝对不是。一个明显的例子是a=DBL_MAX
,b=-DBL_MAX
。然后是t=INFINITY
,因此b+t
也是INFINITY
。
更令人惊讶的是,有些情况下会发生这种情况而没有任何溢出。基本上,它们都是a-b
不精确的形式。例如,如果a
为DBL_EPSILON/4
且b
为-1
,则a-b
为1(假设为默认舍入模式),则a-b+b
为0
我提到第二个例子的原因是,这是强制舍入到IEEE算术中特定精度的规范方法。例如,如果您的数字在[0,1]范围内,并且想强制将其舍入为4位精度,则可以添加然后减去0x1p49
。
答案 1 :(得分:1)
在执行第一次操作的过程中,位可能已从结果的低端丢失。所以有一个问题是,第二项操作是否会完全重现这些损失?我还没有完全想到这一点。
但是,当然,第一次操作可能溢出到+/-无穷大,使第二次比较不相等。
(当然,在使用==
表示浮点值的一般情况下,几乎总是一个错误。)
答案 2 :(得分:-3)
使用花车时不保证任何东西。如果两个数字的指数不同,则算术运算的结果可能无法在浮点数中完全表示。
考虑以下代码:
float a = 0.003f;
float b = 10000000.0f;
float t = a - b;
float x = b + t;
在Visual Studio 2010上运行,您得到t==-10000000.0f
,因此x==0
。
比较浮点数时,不应该使用相等。而是将两个值之间的差值的绝对值与足够小的epsilon值进行比较,以满足您的精度需求。
它变得更奇怪,因为不同的浮点实现可能会为同一操作返回不同的结果。