[英]Migrate from POSIX I/O (open, etc.) to C standard I/O (fopen, etc.)
[英]Can I convert 0.16, 0.32, etc. into an integer properly (16, 32, etc.) in C?
我试图将双247.32
的小数部分转换为整数32
。 我只需要小数点后两位。
我可以将double转换为int并从double减去以获得.32000
然后我可以乘以100得到32.000
但是当我尝试将32.000
为int
,它变成31
。
我可以解决这个问题吗? 我是否应该使用不同于双精度数的数据类型来存储该数字?
谢谢
问题(skjaidev的答案不能解决)是247.32
无法精确表示为二进制浮点数。 实际的存储值可能是:
247.31999999999999317878973670303821563720703125
因此,您不能只舍弃整数部分,再乘以100,然后转换为int
,因为转换会被截断 。
在<math.h>
声明的round()
函数将double
值四舍五入到最接近的整数-尽管结果仍然是double
类型。
double a = 247.32;
a -= trunc(a); /* a == 0.32 -- approximately */
a *= 100.0; /* a == 32.0 -- approximately */
a = round(a); /* a == 32.0 -- exactly */
printf ("%d\n", (int)a);
或者,将计算放在一行中:
double a = 247.32;
printf("%d\n", (int)round(100.0 * (a - trunc(a))));
实际上,这可能是一种更清洁的方法:
double a = 247.32;
printf("%d\n", (int)round(100.0 * fmod(a, 1.0)));
给定输入值x
和输出y
:
char buf[5];
snprintf(buf, sizeof buf, "%.2f", fmod(x, 1.0));
y = strtol(buf+2, 0, 10);
或者只是y = 10*(buf[2]-'0')+buf[3]-'0';
避免strtol
成本。
这是无需自己编写大量代码即可执行所需操作的唯一方法,因为printf
系列函数是唯一能够执行十进制舍入的标准函数。
如果您还有一些其他限制,例如x
非常接近1/100的倍数,则您可能会作弊并执行以下操作:
int y = ((x+0.001)*100;
顺便说一句,如果您的问题涉及金钱, 请不要为了金钱而使用浮点数 ! 使用整数(以美分为单位)或货币的自然最小单位。
由于您只需要查找2个小数位,因此这对我有用:
double a = 247.32;
int b = (int) (a * 100)%100;
printf ("%d\n", b);
更新 :请参阅下面我的评论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.