打印float / double没有尾随零?

时间:2013-03-16 19:08:45

标签: c

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

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

令人讨厌的是,%f说明符只会打印到固定的精度,所以它会向所有未达到该精度的数字添加尾随零。有人提出了%g说明符,它适用于一组数字,但它会切换到某些数字的科学表示法,如下所示:

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

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

5 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:4)

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

尾随零表示对于某些整数x,n,小数值可以写为x/10^n。但是,该标准可以表示的唯一分数对于某些整数x,n具有x/2^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.更好的方式。

答案 2 :(得分:3)

尝试:

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

答案 3 :(得分: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

答案 4 :(得分:-1)

您可以这样打印:

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

要获得更详细的答案,请查看here