两个花车的划分给出了错误的答案

Bri*_*ers 3 c gcc division

尝试使用以下代码在C中划分两个浮点数:

#include <stdio.h>
#include <math.h>

int main(){
  float fpfd = 122.88e6;
  float flo = 10e10;
  float int_part, frac_part;

  int_part = (int)(flo/fpfd);
  frac_part = (flo/fpfd) - int_part;

  printf("\nInt_Part = %f\n", int_part);
  printf("Frac_Part = %f\n", frac_part);

  return(0);
}
Run Code Online (Sandbox Code Playgroud)

对于这段代码,我使用命令:

>> gcc test_prog.c -o test_prog -lm
>> ./test_prog
Run Code Online (Sandbox Code Playgroud)

然后我得到这个输出:

Int_Part = 813.000000
Frac_Part = 0.802063
Run Code Online (Sandbox Code Playgroud)

现在,这个Frac_part似乎是不正确的.我首先在计算器上尝试了相同的等式,然后在Wolfram Alpha中尝试了相同的等式,他们都给了我:

Frac_Part = 0.802083
Run Code Online (Sandbox Code Playgroud)

请注意,小数点后五位的数字是不同的.

这对大多数人来说似乎微不足道,但对于我所做的计算来说,这是至关重要的.

任何人都可以向我解释为什么C代码会出现此错误?

Chr*_*eck 5

当浮点运算的精度不足时,第一个最自然的步骤就是使用更高精度的浮点类型,例如使用double而不是float.(正如其他答案中所指出的那样.)

其次,检查不同的浮点运算并考虑它们的精度.作为错误来源的突出的一个方法是上面的方法,通过简单地转换为int和减去将float分成整数部分和小数部分.这并不理想,因为当你从原始值中减去整数部分时,你正在进行算术,其中涉及的三个数字(两个输入和结果)具有非常不同的比例,这可能会导致精度损失.

我建议使用C <math.h>函数modf将浮点数分成整数和小数部分.http://www.techonthenet.com/c_language/standard_library_functions/math_h/modf.php

(更详细地说:当你进行类似的操作时f - (int)f,浮点加法程序将会看到正在添加一些给定精度X的两个数字,并且它会自然地假设结果也具有精度X.然后它将在该假设下执行实际计算,最后在结束时重新评估结果的精度.因为初始预测结果不理想,一些低阶位将会丢失.)