c语言小数点右移

Moving decimal place to right in c

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

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

#include <stdio.h>

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

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

您可以使用

float f = 120.99f

double f = 120.99

默认情况下,c 将浮点值存储为 double,因此如果将它们存储在 float 变量中,则会发生隐式转换,这很糟糕...
我认为这可行。

使用round函数

float f = 120.99;
int i = round( f * 100.0 );

但是请注意,float 通常只有 6 或 7 位精度,因此有一个最大值可以使用。无法正确转换的最小 float 值是数字 131072.01。如果乘以 100 并四舍五入,结果将为 13107202.

您可以使用 double 值来扩展数字的范围,但即使 double 的范围也是有限的。 (A double 有 16 或 17 位精度。)例如,下面的代码将打印 10000000000000098

double d = 100000000000000.99;
uint64_t j = round( d * 100.0 );
printf( "%llu\n", j );

这只是一个例子,找到超过 double 精度的最小数字留作 reader.

的练习

对整数使用定点运算:

#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);
}

如果您想继续将数字作为浮点数进行运算,那么答案或多或少是。对于 数字,您可以执行各种操作,但随着数字变大,您会遇到问题。

如果您只想打印数字,那么我的建议是将数字转换为字符串,然后将小数点移到那里。这可能会稍微复杂一些,具体取决于您在字符串中表示数字的方式(指数等)。

如果您希望它起作用并且您不介意不使用浮点数,那么我建议您研究任意数量的固定十进制库。

您的问题是浮点数在内部使用 IEEE-754 表示。那是在基数 2 中而不是在基数 10 中。0.25 将有一个精确的表示,但 0.1 没有,120.99 也没有。

真正发生的是,由于浮点数不准确,最接近十进制值120.99乘以100的ieee-754浮点数略低于12099,所以它是截断12098。你的编译器应该警告你你有一个从 float 到 in 的 截断(我的有)。

获得预期结果的唯一万无一失的方法是在截断为 int 之前将 0.5 添加到 float 中:

i = (f * 100) + 0.5

但是注意浮点在处理十进制值时本质上是不准确的。

编辑:

当然对于负数,应该是i = (f * 100) - 0.5 ...