我是C的新手,当我运行下面的代码时,输出的值是12098而不是12099。
我知道使用小数字总是涉及一定程度的不准确,但有没有办法准确地将小数点每次都移动到正确的两个位置?
#include <stdio.h>
int main(void)
{
int i;
float f = 120.99;
i = f * 100;
printf("%d", i);
}
答案 0 :(得分:5)
使用round
功能
float f = 120.99;
int i = round( f * 100.0 );
请注意,float
通常只有6或7位精度,因此有一个最大值可用。无法正确转换的最小float
值是数字131072.01
。如果乘以100并舍入,则结果为13107202
。
您可以使用double
值扩展数字的范围,但即使double
的范围也有限。 (double
具有16或17位精度。)例如,以下代码将打印10000000000000098
double d = 100000000000000.99;
uint64_t j = round( d * 100.0 );
printf( "%llu\n", j );
这只是一个例子,找到最小的数字是超过double
的精确度留给读者的练习。
答案 1 :(得分:4)
对整数使用定点算术:
#include <stdio.h>
#define abs(x) ((x)<0 ? -(x) : (x))
int main(void)
{
int d = 12099;
int i = d * 100;
printf("%d.%02d\n", d/100, abs(d)%100);
printf("%d.%02d\n", i/100, abs(i)%100);
}
答案 2 :(得分:2)
你的问题是浮点数是使用IEEE-754表示的。这是在基数2而不是基数10。0.25
将有一个确切的表示,但0.1
没有,也没有120.99
。
真正发生的是由于浮点不真实,最接近小数值120.99
的ieee-754浮点乘以100
略低于12099
,所以它是截断到12098
。你编译器应该已经警告过你有一个截断从float到in (我的)。
获得预期的唯一简单方法是在截断到int之前将0.5
添加到浮点数:
i = (f * 100) + 0.5
但提防浮点在处理小数值时本质上是不准确的。
编辑:
当然对于负数,它应该是i = (f * 100) - 0.5
...
答案 3 :(得分:1)
如果您想继续使用该号码作为浮点数,那么答案或多或少不。您可以为小数字做各种各样的事情,但随着您的数字越来越大,您将遇到问题。
如果您只想打印该号码,那么我的建议是将号码转换为字符串,然后在那里移动小数点。这可能会稍微复杂,具体取决于您如何表示字符串中的数字(指数和不指数)。
如果您希望这样做,并且您不介意不使用浮点数,那么我建议您研究任意数量的固定十进制库。
答案 4 :(得分:0)
您可以使用
float f = 120.99f
或
double f = 120.99
默认情况下,c将浮点值存储为double,因此如果将它们存储在float变量中,则会发生隐式转换并且它很糟糕...
我认为这很有效。