6

在比较双精度数是否相等时,我们需要给出一个容差水平,因为浮点计算可能会引入错误。例如:

double x; 
double y; 
x = f();
y = g();

if (fabs(x-y)<epsilon) {
   // they are equal!
} else {
   // they are not!
}

但是,如果我只是简单地分配一个常数值,而不进行任何计算,我还需要检查 epsilon 吗?

double x = 1;
double y = 1;

if (x==y) {
   // they are equal!
} else {
   // no they are not!
}

==比较够好吗?还是我需要再做fabs(x-y)<epsilon一次?分配时是否可能引入错误?我是不是太偏执了?

铸造 ( double x = static_cast<double>(100)) 怎么样?这也会引入浮点错误吗?

我在 Linux 上使用 C++,但如果它因语言而异,我也想理解这一点。

4

5 回答 5

3

实际上,这取决于价值和实施。C++ 标准(草案 n3126)有这样的说法2.14.4 Floating literals

如果缩放值在其类型的可表示值范围内,则结果是缩放值(如果可表示),否则以实现定义的方式选择最接近缩放值的更大或更小的可表示值。

换句话说,如果该值是完全可表示的(并且1在 IEEE754 中,就像100在您的静态转换中一样),您将获得该值。否则(例如 with 0.1),您将获得实现定义的紧密匹配(a)。现在我会非常担心基于相同输入标记选择不同紧密匹配的实现,但这可能的。


(a)实际上,该段落可以通过两种方式阅读,要么实现可以自由选择最接近的较高值或最接近的较低值,而不管哪个实际上是最接近的,或者它必须选择最接近所需值的值。

如果是后者,它不会改变这个答案,但是因为您所要做的就是在两个可表示类型的中点处硬编码一个浮点值,并且实现可以再次自由选择任何一个。

例如,它可能会在下一个较高值和下一个较低值之间交替,原因与应用银行家四舍五入的原因相同 - 以减少累积误差。

于 2012-03-23T05:36:59.077 回答
0

不,如果您分配文字,它们应该是相同的:)

此外,如果您从相同的值开始并执行相同的操作,它们应该是相同的。

浮点值不准确,但操作应该产生一致的结果:)

于 2012-03-23T04:49:43.800 回答
0

这两种情况最终都取决于实现定义的表示。

浮点值及其表示形式的存储可能有多种形式——按地址加载还是常量加载?通过快速数学优化?寄存器宽度是多少?它是否存储在 SSE 寄存器中?存在许多变化。

如果您需要精确的行为和可移植性,请不要依赖此实现定义的行为。

于 2012-03-23T05:57:43.193 回答
0

IEEE-754 是浮点数遵循的标准通用实现,它要求浮点运算来产生最接近无限精确结果的可表示值的结果。因此,您将面临的唯一不精确是在您执行的每个操作之后进行舍入,以及在链中较早执行的操作中传播舍入误差。浮点数本身并不是不精确的。顺便说一句,epsilon 可以而且应该被计算,你可以参考任何关于它的数字书。

浮点数可以精确地表示整数,直到其尾数的长度。因此,例如,如果您从 int 转换为 double,它将始终是精确的,但对于转换为 float,它对于非常大的整数将不再精确。

有一个广泛使用浮点数代替整数的主要例子,它是 LUA 脚本语言,它没有内置整数类型,浮点数被广泛用于逻辑和流控制等。性能使用浮点数的存储代价比在运行时解析多种类型的代价要小,并使实现更轻。LUA 不仅在 PC 上得到了广泛的应用,在游戏机上也得到了广泛的应用。

现在,许多编译器都有一个禁用 IEEE-754 兼容性的可选开关。然后做出妥协。非规格化数字(指数达到可能值最小的非常小的数字)通常被视为零,并且可以进行幂、对数、sqrt 和 1/(x^2) 的近似值,但可以进行加法/减法,对于可以精确表示的数字,比较和乘法应该保留它们的属性。

于 2012-03-23T06:05:42.433 回答
0

简单的答案:对于常量 == 是可以的。您应该注意两个例外情况:

第一个例外:

0.0 == -0.0

对于 IEEE 754 标准,有一个比较相等的负零。这意味着 1/INFINITY == 1/-INFINITY 打破 f(x) == f(y) => x == y

第二个例外:

南!=南

This is a special caveat of NotaNumber which allows to find out if a number is a NaN on systems which do not have a test function available (Yes, that happens).

于 2012-03-23T17:21:42.833 回答