Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 两个浮点数的划分给出了错误的答案_C_Gcc_Division - Fatal编程技术网

C 两个浮点数的划分给出了错误的答案

C 两个浮点数的划分给出了错误的答案,c,gcc,division,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

尝试使用以下代码在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);
}
然后我得到这个输出:

Int_Part = 813.000000
Frac_Part = 0.802063
现在,这个分形部分似乎不正确。我先在计算器上试过同样的方程式,然后在Wolfram Alpha中试过,他们都给了我:

Frac_Part = 0.802083
请注意,小数点后第五位的数字是不同的

这对大多数人来说似乎无关紧要,但对于我正在做的计算来说,这是至关重要的


有人能给我解释一下为什么C代码会出现这种错误吗?

float
只有6~9个有效数字,对于大多数实际应用来说不够精确。将所有
float
变量更改为
double
(提供15~17个有效数字)将产生以下输出:

Int\u Part=813.000000
压裂部分=0.802083

当浮点运算的精度不足时,最自然的第一步是只使用精度更高的浮点类型,例如使用
双精度
而不是
浮点
。(正如其他答案中立即指出的。)

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

我建议使用C
函数
modf
将浮点数拆分为整数和小数部分


(更详细:当您执行类似
f-(int)的操作时)f
,浮点加法过程将看到两个给定精度X的数字被相加,它自然会假设结果也有精度X。然后它将在该假设下执行实际计算,最后重新评估结果的精度。因为ial预测结果并不理想,一些低阶位将丢失。)

浮点是单精度浮点,您应该尝试使用双精度,以下代码给出了正确的结果:

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

int main(){
  double fpfd = 122.88e6;
  double flo = 10e10;
  double 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);
}
#包括
#包括
int main(){
双fpfd=122.88e6;
双flo=10e10;
双内件、压裂件;
int_部分=(int)(flo/fpfd);
压裂部分=(flo/fpfd)-内部部分;
printf(“\n部分=%f\n”,内部部分);
printf(“压裂部分=%f\n”,压裂部分);
返回(0);
}
为什么? 正如我所说,浮点是单精度浮点,它们比double小(在大多数体系结构中,
sizeof(float)
)。
通过使用
double
而不是
float
,您将有更多的位来存储尾数和数字的指数部分(请参阅)。

这不是C,而是标准浮点类型的属性。你认为什么可以用固定的位数来表示?做一些关于浮点(算术)的研究。你试过使用
double
?时间到了。我认为这不是一个好的复制品。这个问题与一般的浮点精度问题无关。毕竟,在
float
上使用
double
仍然无法避免浮点精度问题,但它确实给出了预期的结果。“
float
只有7个有效数字,在实际应用中不够精确。”我的意思是,这不是真的,对吗?它对于OpenGL来说已经足够了,而OpenGL在实际应用中肯定占很大一部分。它更像是,它通常不适合于数值实验/科学数据分析。@ChrisBeck 7是
float
通常提供的。我已经编辑成更精确的版本。我仍然认为在大多数实际应用中不够精确的部分是正确的,在现代机器上,
double
的算术通常比t
float
快。注:C保证
float
至少有6位小数精度<代码>双至少有10位十进制数字。对于C帖子:不是引用C++站点,而是从C++库<代码> CMASUD/COD>中建议函数<代码> MODFE()/CUT>,推荐C99函数<代码>浮点MODFF(浮点值,浮点*IPTR);代码>更有意义这是一个很好的观点,编辑了问题。奇怪的是,维基百科也提到了这一点:你的评论的ref IMO更好。当然,该标准是“最佳”的,但作为派生位置(如en.cppreference)并不容易理解。
#include <stdio.h>
#include <math.h>

int main(){
  double fpfd = 122.88e6;
  double flo = 10e10;
  double 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);
}