Ash*_*ave 4 c floating-point comparison
可能重复:
浮点比较中的问题
#include <stdio.h>
#include <conio.h>
main()
{
float a = 0.7;
if(a < 0.7)
printf("C");
else
printf("C++");
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,输出是C.我在Code :: Blocks和Pelles C中尝试了这个代码,但得到了相同的答案.我想详细了解这个的原因!
Ste*_*non 20
在二进制中,0.7是:
b0.1011001100110011001100110011001100110011001100110011001100110...
Run Code Online (Sandbox Code Playgroud)
但是,0.7是一个双精度文字,其值为0.7舍入到最接近的可表示的双精度值,即:
b0.10110011001100110011001100110011001100110011001100110
Run Code Online (Sandbox Code Playgroud)
十进制,这正是:
0.6999999999999999555910790149937383830547332763671875
Run Code Online (Sandbox Code Playgroud)
写入时float a = 0.7,该double值再次舍入为单精度,并a获取二进制值:
b0.101100110011001100110011
Run Code Online (Sandbox Code Playgroud)
这正是
0.699999988079071044921875
Run Code Online (Sandbox Code Playgroud)
十进制.
进行比较时(a < 0.7),您将此单精度值(转换为double,因为所有单精度值都可以双精度表示)与原始双精度值进行比较.因为
0.699999988079071044921875 < 0.6999999999999999555910790149937383830547332763671875
Run Code Online (Sandbox Code Playgroud)
比较正确返回true,并打印您的程序"C".
请注意,这在C++中没有任何不同,相反的代码的出现.某些(数字上不安全的)编译器优化可以改变行为,但这些优化并不是C或C++独有的.
这是因为0.7有类型double,所以a转换为double和这种类型进行比较.由于0.7在二进制浮点中无法准确表示,因此会出现一些舍入误差,并且比较变为真.
您可以:
if( a < 0.7f ) {
....
Run Code Online (Sandbox Code Playgroud)
但实际上这种效果对C++也是如此,所以你的条件并不完全正确.