C++ 浮点比较 intmain() { 浮动a=0.7; 浮动b=0.5; 如果(a

C++ 浮点比较 intmain() { 浮动a=0.7; 浮动b=0.5; 如果(a,c++,c,floating-point,C++,C,Floating Point,我本以为这段代码的输出是0如果正确。 但令我沮丧的是,输出是1是正确的为什么?intmain() int main() { float a = 0.7; float b = 0.5; if (a < 0.7) { if (b < 0.5) printf("2 are right"); else printf("1 is right"); } else printf("0 are right")

我本以为这段代码的输出是
0如果正确
。 但令我沮丧的是,输出是
1是正确的
为什么?

intmain()
int main()
{
    float a = 0.7;
    float b = 0.5;
    if (a < 0.7)
    {
       if (b < 0.5) printf("2 are right");
       else         printf("1 is right");
    }
    else printf("0 are right");
}
{ 浮点a=0.7,b=0.5;//这些是浮点 if(a<.7)//这是双精度的 { if(b<0.5)//这是双精度的 printf(“2是正确的”); 其他的 printf(“1是正确的”); } 其他的 printf(“0是正确的”); }
在比较过程中,浮点数被提升为双精度浮点数,由于浮点数的精度低于双精度浮点数,因此0.7作为浮点数与0.7作为双精度浮点数不同。在这种情况下,0.7 as float在升级时会低于0.7 as double。正如Christian所说,0.5是2的幂,它总是精确地表示出来,所以测试的结果和预期的一样:
0.5<0.5
是错误的

因此,要么:

  • float
    更改为
    double
    ,或:
  • .7
    .5
    更改为
    .7f
    .5f

您将获得预期的行为。

问题是,您要比较的常量是
而不是
浮点
。此外,将常数更改为易于表示的值,例如系数
5
,将表明
0是正确的
。比如说,

int main()
{
    float a = 0.7, b = 0.5; // These are FLOATS
    if(a < .7)              // This is a DOUBLE
    {
      if(b < .5)            // This is a DOUBLE
        printf("2 are right");
      else
        printf("1 is right");
    }
    else
      printf("0 are right");
}
这个迷人的语法意味着把f1的地址当作 整数指针,并取消对它的引用。所有这些指针操作看起来 昂贵,但它们基本上都是取消的,只是意味着“享受f1” 作为一个整数'。因为我们对整行应用相同的语法 表示“使用f1和f2的内存表示法进行比较” 解释为整数而不是浮点数'


这是由于从浮点转换为双精度时的舍入问题。另外,顺便说一句,您的逻辑中有一个错误,即0是正确的。当输出0正确时,不检查b。但是你真正想要完成的事情有点神秘。浮点和双精度之间的浮点比较将有变化,分钟,因此您应该根据您的情况与增量“可接受”变化进行比较。我总是通过内联函数来完成这项工作(用一个宏做了一次,但是太麻烦了)。不管怎么说,这类例子中有很多舍入问题。阅读浮点的内容,知道.7与.7f不同,将.7赋给浮点会将一个double转换为浮点,从而改变值的确切性质。但是,自从你检查了a之后,编程假设b是错误的,我必须注意:)

一般来说,将相等与浮点数进行比较是一件危险的事情(这实际上是你在>>的边界上进行比较时所做的),记住小数点后的某些分数(如1/3)不能精确地表达,同样可以说是二进制的

0.5=0.1
,在浮点或双精度中相同

0.7=0.10110011001100
等永远,0.7不能用二进制精确表示,您会得到舍入误差,并且浮点和双精度之间可能(非常微小)不同


请注意,在浮点和双精度之间进行运算时,会截断不同的小数位数,因此结果不一致。

第一个if和第二个if的计算方法应该相同,对吗??所以答案应该是
2是正确的
或者
0是正确的
,但是为什么
1是正确的
?+1是唯一一个在看到问题时没有喊出“从不比较浮点”并真正思考这里到底发生了什么的答案。假设IEEE 754浮点,行为是100%可预测的<代码>0.7成为最接近的
双精度
(0.69999999999555910790149938383830547332763671875)并将其转换为
浮点
四舍五入到最接近的
浮点
值(0.69999988079071044921875)@sasidhar:0.7表示为float,存储为
0.6999999988079071044921875
,存储为double,存储为
0.699999999955591079014994
,因此有
0.0000000 1192092891066920414994
的差异,在分配给
a
期间丢失该信息,当
a
转换为双精度。@sasidhar:您应该假设所有浮点数都不会被精确存储,并且它们会丢失一些信息。(因此,不应精确地比较浮点值,而应在一定的误差范围内进行比较)。注意:如果变量得到优化,并且在程序期间所有值都保留在寄存器中,那么您可能会得到不同的结果。尝试在发布模式下编译,并将优化器转到其最高级别,然后查看结果是否更改。整数比较假定
sizeof(int)==sizeof(float)
。在处理
double
时,一个更糟糕的假设。它还违反了严格的别名规则。您应该阅读。0.7不是浮点,而是双精度。这可能是这种行为的一个原因,一个原因是
a
float
.7
double
。米奇,如果
0.7==0.7
答案是
0是正确的
很好。很晚了。我应该停止了!。。。。。
main()
{
    float a=0.25,b=0.5; 
    if(a<.25) 
       {
       if(b<.5) 
               printf("2 are right");
       else
               printf("1 is right");
       }
else
printf("0 are right");
}
if (*(int*)&f1 < *(int*)&f2)