常量赋值的浮点比较

Ven*_*tta 5 c++ floating-point floating-point-precision

当比较双精度时,我们需要给出容差级别,因为浮点计算可能会引入错误.例如:

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

if (fabs(x-y)<epsilon) {
   // they are equal!
} else {
   // they are not!
}
Run Code Online (Sandbox Code Playgroud)

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

double x = 1;
double y = 1;

if (x==y) {
   // they are equal!
} else {
   // no they are not!
}
Run Code Online (Sandbox Code Playgroud)

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

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

我在Linux上使用C++,但如果它因语言而异,我也想了解它.

pax*_*blo 3

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

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

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


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

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

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