Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 打印不带尾随零的浮点/双精度?_C - Fatal编程技术网

C 打印不带尾随零的浮点/双精度?

C 打印不带尾随零的浮点/双精度?,c,C,有几个问题与此相关,但我没有看到一个正确回答这个问题。我想打印一个浮点数,但我希望小数位数是自适应的。例如: 0 -> 0 1234 -> 1234 0.1234 -> 0.1234 0.3 -> 0.3 令人烦恼的是,%f说明符只会以固定的精度打印,因此它会向所有未达到该精度的数字添加尾随零。有些人建议使用%g说明符,该说明符适用于一组数字,但对于某些数字,它将切换为科学符号,如下所示: printf("%g", 1000000.0); // pr

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

0      -> 0
1234   -> 1234
0.1234 -> 0.1234
0.3    -> 0.3
令人烦恼的是,
%f
说明符只会以固定的精度打印,因此它会向所有未达到该精度的数字添加尾随零。有些人建议使用
%g
说明符,该说明符适用于一组数字,但对于某些数字,它将切换为科学符号,如下所示:

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

如何在不使用不必要的零的情况下打印浮点数,同时仍保持printf对实际包含小数部分的数字的标准精度?

您可以这样打印:

printf("%g", 1000000.0); // prints 1e+06
printf("%.0f", 1000000.0);
要获得更详细的答案,请查看。

尝试:

printf("%.20g\n", 1000000.0); // = 1000000
这将在20位有效数字后切换为科学记数法(默认为“%g”的6位之后):

但要注意双重精度:

printf("%.20g\n", 0.12345);   // = 0.12345000000000000417
printf("%.15g\n", 0.12345);   // = 0.12345

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

问题在于,使用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.更好的方法了。

我自己用前面提到的方法编写了一个小函数来实现这一点,这里是一个测试仪。我不能保证它没有bug,但我认为它很好

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

printf(“%.0f”,0.1234)打印“0”。我认为OP不希望这样。“我如何打印浮点数而不需要不必要的零,但也不舍入或截断值?”是打印0的答案,因为is不会在点(分数部分)后打印,这将截断数字,不是吗?@metable如果您打印一个变量,那么该格式将不会更改您的变量。这只是一种打印格式numbers@nabroyan问题明确指出,0.1234应打印为0.1234。这不是你的答案,好主意。但是
0.1234
将在IEEE双精度中表示为
0.1233999999999580335[…]
。没有尾随的“0”字符。将其四舍五入到机器精度的几倍,然后修剪零。@flyingOwl,
snprintf
会为您解决这个问题。这就是重点。如果没有
snprintf
,小数点的四舍五入是非常困难的。@R。。从技术上讲,这不是只是截断,而不是舍入吗?还是我遗漏了什么?明白。所以也许我想四舍五入说,小数点后8位,也就是0.12340000。我仍然希望能够打印这个舍入值而不需要额外的零。没有骰子
printf(“%.15g”,0.00001)
仍然打印
1e-05
@AlexeyFrunze我不认为这是重复的,因为它比我想要的要复杂得多。我可以舍入到几个数字,我只是不想要任何尾随的零。但这正是你所要求的,引用:
我如何打印浮点数字而不需要不必要的零,也不需要舍入或截断值?
@AlexeyFrunze啊,我这样做了,我的错。这更多是指类似问题的“答案”,建议使用
%.2f
或类似方法。我对它进行了编辑以删除该语言。但现在该语言很模糊。定义
对需要它的数字有相当好的精确度
@AlexeyFrunze我指的是printf对实际有小数成分的数字的标准精确度(我相信是小数点后6位)。再说一次,我不希望它是超精确的,我对printf的精确性很好,我只是讨厌后面所有的零。