为什么roundf()不循环浮点值,为什么int-float数学运算会返回错误的值?

Mar*_*nak 3 c floating-point

我不明白为什么不roundf()从功能math.h全面的donation变量,而这轮livestockPM没有问题.我需要使用舍入值进行其他计算,但我printf用来检查值是否正确,并且它只返回错误的值(不会舍入变量donation).此外,变量final只返回值,好像四舍五入为.00,无论什么变量farmer1,2,3保持.

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

int main(){
   int farmer1 = 9940;
   int farmer2 = 4241;
   int farmer3 = 7779;

   float livestockPM = (float)farmer1 / (float)farmer2;
   printf("livestock: %f\n",livestockPM);

   livestockPM = roundf(livestockPM * 100) / 100;
   printf("livestock rounded: %f\n",livestockPM);

   float donation = (float)livestockPM * (float)farmer3;
   printf("donation: %f\n", donation);

   donation = roundf(donation * 100.00) / 100.00;
   printf("donation rounded: %f\n", donation);

   float final = donation * (float)farmer2;
   printf("final: %f\n", final);

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

输出:

livestock: 2.343787
livestock rounded: 2.340000
donation: 18202.859375
donation rounded: 18202.859375
final: 77198328.000000
Run Code Online (Sandbox Code Playgroud)

任何人都知道为什么?我在考虑因为浮点数乘以int,但我似乎无法让它像这样工作.我试过从整数变量中删除(float),但结果也不合适.谢谢.

chu*_*ica 5

OP float是使用二进制浮点编码的,并且18202.859375缺少精度来获取"%f"打印为的值18202.860000.

A float不能代表所有可能的数字.作为二进制浮点数,它可以表示如下的数字.请参阅IEEE 754转换器,但不介于两者之间.

18202.859375
18202.86138125
Run Code Online (Sandbox Code Playgroud)

执行以下操作时,将再次获得最佳结果18202.859375.

float donation_rounded = roundf(18202.859375 * 100.00) / 100.00;
Run Code Online (Sandbox Code Playgroud)

回想一下,printf("%f\n", x)打印一个以文本方式舍入到最接近的0.000001值的数字.

代码可以使用double,但同样的问题会出现非常大的数字,但可能满足OP的迫切需要.@ user3386109


由于OP似乎试图应对资金,因此标准C中没有很好的解决方案.最好的货币/货币表示会涉及到一些问题.