为啥 roundf() 不对浮点值进行舍入,为啥 int - float 数学运算返回错误值?
Posted
技术标签:
【中文标题】为啥 roundf() 不对浮点值进行舍入,为啥 int - float 数学运算返回错误值?【英文标题】:Why doesn't roundf() round a float value and why do int - float math operations return wrong values?为什么 roundf() 不对浮点值进行舍入,为什么 int - float 数学运算返回错误值? 【发布时间】:2016-12-03 00:53:34 【问题描述】:我不明白为什么math.h
中的roundf()
函数不围绕donation
变量,而它却毫无问题地围绕livestockPM
。我需要将舍入值用于其他计算,但我使用printf
检查值是否正确,它只是返回错误值(不舍入变量donation
)。此外,变量final
仅返回值,好像四舍五入到 0.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;
输出:
livestock: 2.343787
livestock rounded: 2.340000
donation: 18202.859375
donation rounded: 18202.859375
final: 77198328.000000
有人知道为什么吗?我在想是因为将浮点数与 int 相乘,但我似乎无法让它像这样工作。我尝试从整数变量中删除 (float),但结果也不理想。谢谢。
【问题讨论】:
float
只有 6 或 7 位精度。将所有float
s 更改为double
,并使用round
,而不是roundf
。
@user3386109 谢谢,确实有效!
【参考方案1】:
OP 的 float
是使用 二进制 浮点编码的,18202.859375
缺乏精度,无法采用 "%f"
打印为 18202.860000
的值。
float
不能代表所有可能的数字。作为二进制浮点数,它可以表示如下数字。请参阅IEEE 754 Converter,但不要介于两者之间。
18202.859375
18202.86138125
当以下执行时,最好的结果还是18202.859375
。
float donation_rounded = roundf(18202.859375 * 100.00) / 100.00;
回想一下,printf("%f\n", x)
会打印一个以文本形式四舍五入到最接近 0.000001 值的数字。
代码可以使用double
,但同样的问题会出现在非常大的数字上,但可能会满足OP的迫切需要。 @user3386109
由于 OP 似乎正在努力解决金钱问题,标准 C 中没有伟大的解决方案。best money/currency representation 解决了一些问题。
【讨论】:
以上是关于为啥 roundf() 不对浮点值进行舍入,为啥 int - float 数学运算返回错误值?的主要内容,如果未能解决你的问题,请参考以下文章