有一些与此相关的问题,但我没有看到一个正确回答这个问题的问题。我想打印一个浮点数,但我希望小数位数是自适应的。举个例子:
0 -> 0
1234 -> 1234
0.1234 -> 0.1234
0.3 -> 0.3
令人讨厌的是,%f
说明符只会打印到固定的精度,所以它会向所有未达到该精度的数字添加尾随零。有人提出了%g
说明符,它适用于一组数字,但它会切换到某些数字的科学表示法,如下所示:
printf("%g", 1000000.0); // prints 1e+06
如何在没有不必要的零的情况下打印浮点数,同时仍然保持printf对实际具有小数分量的数字的标准精度?
答案 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)