一个简单的浮动加法产生一个错误的结果

问题描述:

这些数字加起来为零,但代码输出结果为18。 对于我的任务,它要求将数字定义为浮点数。一个简单的浮动加法产生一个错误的结果

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char** argv) { 


float b1 = 23.0; 
float b2 = 42.0; 
float b3 = 2073741824.0; 
float b4 = -2073741714.0; 
float b5 = -64.0; 
float b6 = -111.0; 
float be; 

be = b1+b2+b3+b4+b5+b6; 

printf("Das Float Ergebnis ist: %f\n", be); 

return (EXIT_SUCCESS); 
} 
+0

你正在运行到一系列问题,以'floats' –

+1

第1步:'B1 + B2 + B3 + B4 + B5 + b6' - >'B1 + B2 +(B3 + B4)+ B5 + b6' – chux

+2

如果你使用double而不是float,你应该有足够的精度来处理这些数字(当内存不是问题时,float没什么意义)。 –

-2073741714.0通常不是精确地表示为一个float。使用更宽的类型或接受不精确。作为32位变量的float不能准确地编码每个编号,只有约2 其中。典型的最接近的是-2073741696

float b4 = -2073741714.0; 
printf("b4 = %f\n", b4); 
// typical output 
// b4 = -2073741696.000000 

而是考虑更宽的FP类型。

int main(void) { 
    double b1 = 23.0; 
    double b2 = 42.0; 
    double b3 = 2073741824.0; 
    double b4 = -2073741714.0; 
    double b5 = -64.0; 
    double b6 = -111.0; 
    double be; 
    printf("b4 = %f\n", b4); 

    be = b1 + b2 + (b3 + b4) + b5 + b6; 
    printf("Das Float Ergebnis ist: %f\n", be); // Das Float Ergebnis ist: 0.000000 
    return (EXIT_SUCCESS); 
} 

或者使用更广泛的数学

int main(void) { 
    float b1 = 23.0; 
    float b2 = 42.0; 
    float b3 = 2073741824.0; 
    double b4 = -2073741714.0; 
    float b5 = -64.0; 
    float b6 = -111.0; 
    float be; 
    printf("b4 = %f\n", b4); 

    be = b1 + b2 + (b3 + b4) + b5 + b6; 
    printf("Das Float Ergebnis ist: %f\n", be); // Das Float Ergebnis ist: 0.000000 
    return (EXIT_SUCCESS); 
} 

一个第三选择是重新安排的评估顺序。这将有所帮助,但尚未克服float的限制。

int main(void) { 
    float b1 = 23.0; 
    float b2 = 42.0; 
    float b3 = 2073741824.0; 
    float b4 = -2073741714.0; 
    float b5 = -64.0; 
    float b6 = -111.0; 
    float be; 

    be = b1 + b2 + (b3 + b4) + b5 + b6; 
    printf("Das Float Ergebnis ist: %f\n", be); // Das Float Ergebnis ist: 18.000000 
    return (EXIT_SUCCESS); 
} 

有人会说,一个浮动的准确宽度是不确定的由C standard,因此实现相关的,但是任何平台,你可能会遇到一个C floatIEEE754single-precision数。

如果您有兴趣,这里有很多数学,但简而言之,float可以存储约7-8 significant decimal digits。让我来说明这一个例子:

2073741824.0; // float 
     ^^^^// all this information is most likely lost 

通过最有可能我的意思是你应该NEVER认为该计划将remeber这些数字。

2073741xxx.x; // float 
     ^^^^// this is how you should treat you number form a safe programmer's prespective 
+2

谢谢你的优秀解释。这在我阅读的任何教程中都没有提及。 – DerEntinator

+1

“float可以存储约7-8个重要的十进制数字”是一个好的近似值。 [二进制](https://en.wikipedia.org/wiki/IEEE_754)在最坏情况下有6位重要的十进制数字(研究'FLT_DIG')。 6-9将是一个更好的概括。 – chux