在c中向右移动小数位

时间:2015-02-04 17:44:24

标签: c double decimal

我是C的新手,当我运行下面的代码时,输​​出的值是12098而不是12099。

我知道使用小数字总是涉及一定程度的不准确,但有没有办法准确地将小数点每次都移动到正确的两个位置?

#include <stdio.h>

int main(void)
{
    int i;
    float f = 120.99;

    i = f * 100;
    printf("%d", i);
}

5 个答案:

答案 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变量中,则会发生隐式转换并且它很糟糕...
我认为这很有效。