for*_*818 15 c++ floating-point equality
我知道,为了比较两个浮点值,需要使用一些epsilon精度,因为它们并不精确.但是,我想知道是否有边缘情况,我不需要那个epsilon.
特别是,我想知道做这样的事情总是安全的:
double foo(double x){
if (x < 0.0) return 0.0;
else return somethingelse(x); // somethingelse(x) != 0.0
}
int main(){
int x = -3.0;
if (foo(x) == 0.0) {
std::cout << "^- is this comparison ok?" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道有更好的方法可以编写foo
(例如,另外返回一个标志),但我想知道一般情况下是否可以分配0.0
给浮点变量然后将其与之比较0.0
.
或者更一般,以下比较是否总是如此?
double x = 3.3;
double y = 3.3;
if (x == y) { std::cout << "is an epsilon required here?" << std::endl; }
Run Code Online (Sandbox Code Playgroud)
当我尝试它时,似乎工作,但可能是一个人不应该依赖它.
是的,在这个例子中,检查== 0.0
. 这不是因为0.0
它在任何方面都很特殊,而是因为您只分配一个值并在之后进行比较。您也可以将其设置为3.3
并比较 for == 3.3
,这也可以。您正在存储一个位模式,并针对完全相同的位模式进行比较,只要这些值没有被提升为另一种类型来进行比较。
然而,在数学上等于零的计算结果并不总是等于0.0
。
这个问答已经发展到还包括程序的不同部分由不同的编译器编译的情况。问题没有提到这一点,我的回答仅适用于所有相关部分使用相同编译器的情况。
C++ 11 标准,
§5.10相等运算符
6 如果两个操作数都是算术或枚举类型,则对两个操作数进行通常的算术转换;如果指定的关系为真,则每个运算符都应为真,如果为假,则为假。
关系没有进一步定义,因此我们必须使用“平等”的常见含义。
§2.13.4浮动文字
1 [...] 如果缩放值在其类型的可表示值范围内,则结果是可表示的缩放值,否则以实现定义的方式选择最接近缩放值的较大或较小的可表示值。[...]
当值不可表示时,编译器必须在转换文字时恰好在两个值之间进行选择。如果始终为相同的文字选择相同的值,则可以安全地比较诸如3.3
, 之类的值,因为==
表示“相等”。
是的,如果你回来,0.0
你可以将它与之比较0.0
; 0可以完全表示为浮点值.如果你返回,3.3
你必须要小心,因为3.3
不能完全表示,所以从double到float的转换会产生不同的值.
归档时间: |
|
查看次数: |
4508 次 |
最近记录: |