6

有几个与此相关的问题,但我还没有看到一个正确回答这个问题的问题。我想打印一个浮点数,但我希望小数位数是自适应的。举个例子:

0      -> 0
1234   -> 1234
0.1234 -> 0.1234
0.3    -> 0.3

令人讨厌的是,说明%f符只会打印到固定的精度,因此它将在所有未达到该精度的数字上添加尾随零。有些人建议使用%g说明符,它适用于一组数字,但它会切换到一些数字的科学记数法,如下所示:

printf("%g", 1000000.0); // prints 1e+06

如何在没有不必要的零的情况下打印浮点数,同时仍然保持 printf 对实际具有小数分量的数字的标准精度?

4

5 回答 5

11

用于snprintf打印到临时缓冲区,然后'0'手动删除尾随字符。没有其他方法既正确又易于实施。

于 2013-03-16T19:25:18.360 回答
5

问题是使用 IEEE 标准 754 表示,浮点值(带有小数部分)永远不能有“尾随零”。

尾随零表示小数值可以写成x/10^n某些整数 x、n。但是这个标准唯一可以表示的分数具有x/2^n某些整数 x、n 的形式。

所以你写的 0.1234 用字节 0x3D 0xFC 0xB9 0x24 表示。这是:

Sign = 0
Exponent = 01111011 (which means -4)
Significand: 1.11111001011100100100100

有效数字表示:1 + 1/2 + 1/4 + 1/8 + 1/16 + 0/32 + 0/64 + 1/128 + 0/256 + 1/512 + 1/1024 + 1/2048 + 0/4096 + 0/8192 + ...

如果执行此计算,您将得到 1.974400043487548828125。

所以数字是+ 1.974400043487548828125 * 2^(-4)=0.1234000027179718

(当然,我是用电脑计算的,所以它可能出于同样的原因关闭......)

如您所见,计算机不想为您决定要在 4 位(仅)而不是 9 位(0.123400002)之后砍掉这个数字。关键是计算机不会将此数字视为 0.1234 并带有无限数量的尾随零。

所以我认为没有比 R.'s 更好的方法了。

于 2013-03-16T19:44:07.313 回答
4

尝试:

printf("%.20g\n", 1000000.0); // = 1000000

这将在 20 位有效数字后切换到科学记数法(默认为“%g”的 6 位数字之后):

printf("%.20g\n", 1e+19); // = 10000000000000000000
printf("%.20g\n", 1e+20); // = 1e+20

但要小心双精度:

printf("%.20g\n", 0.12345);   // = 0.12345000000000000417
printf("%.15g\n", 0.12345);   // = 0.12345
于 2013-03-16T19:23:43.903 回答
0

我使用已经提到的方法自己编写了一个小函数来执行此操作,这里是使用测试仪。我不能保证它没有错误,但我认为这很好。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *convert(char *s, double x);

int main()
{
    char str[3][20];
    printf("%s\n%s\n%s\n", convert(str[0], 0),
          convert (str[1], 2823.28920000),
          convert (str[2], 4.000342300));

}

char *convert(char *s, double x)
{
    char *buf = malloc(100);
    char *p;
    int ch;

    sprintf(buf, "%.10f", x);
    p = buf + strlen(buf) - 1;
    while (*p == '0' && *p-- != '.');
    *(p+1) = '\0';
    if (*p == '.') *p = '\0';
    strcpy(s, buf);
    free (buf);
    return s;
}

输出:

0
2823.2892
4.0003423
于 2013-03-16T19:52:50.360 回答
-1

你可以这样打印:

printf("%.0f", 1000000.0);

如需更详细的答案,请查看此处

于 2013-03-16T19:11:51.820 回答