C 为什么带%f的printf()有时会在小数点后丢失一个数字?

C 为什么带%f的printf()有时会在小数点后丢失一个数字?,c,linux,C,Linux,为什么这个声明 printf("%f", sensorvalue) 大多数情况下,打印像“11312.96”这样的字符串(小数点后有两位数字),但有时打印像“11313.1”这样的字符串(小数点后有一位数字)传感器值从功率计连续读取。不同时间的值应该具有相同的格式 它是在Linux上运行的C 为什么语句printf(“%f”,sensorvalue)最多打印11312.96这样的字符串(小数点后有两位数字),但有时打印11313.1这样的字符串(小数点后有一位数字) 即使“它是在Linux上运

为什么这个声明

printf("%f", sensorvalue)
大多数情况下,打印像“11312.96”这样的字符串(小数点后有两位数字),但有时打印像“11313.1”这样的字符串(小数点后有一位数字)<代码>传感器值从功率计连续读取。不同时间的值应该具有相同的格式

它是在Linux上运行的C

为什么语句
printf(“%f”,sensorvalue)
最多打印11312.96这样的字符串(小数点后有两位数字),但有时打印11313.1这样的字符串(小数点后有一位数字)

即使“它是在Linux上运行的C”,该库也不符合C

产量

printf("%f\n", 11312.96f);
printf("%f\n", 11312.96);
printf("%f\n", 11313.1f);
printf("%f\n", 11313.1);
。。。预计如下所示,
”后面有6个数字。
-可能最小数字的值有所变化。即使是不同质量的实现,输出也应该是
后面的6位。

11312.959961
11312.960000
11313.099609
11313.100000
如果格式为
“%g”
,则可能会出现如下输出

11313
11313
11313.1
11313.1
为什么语句
printf(“%f”,sensorvalue)
最多打印11312.96这样的字符串(小数点后有两位数字),但有时打印11313.1这样的字符串(小数点后有一位数字)

即使“它是在Linux上运行的C”,该库也不符合C

产量

printf("%f\n", 11312.96f);
printf("%f\n", 11312.96);
printf("%f\n", 11313.1f);
printf("%f\n", 11313.1);
。。。预计如下所示,
”后面有6个数字。
-可能最小数字的值有所变化。即使是不同质量的实现,输出也应该是
后面的6位。

11312.959961
11312.960000
11313.099609
11313.100000
如果格式为
“%g”
,则可能会出现如下输出

11313
11313
11313.1
11313.1

如果您完全按照规定使用
%f
,这实际上违反了标准(这是不寻常的,但肯定不是闻所未闻的),该标准在
C11 7.21.6.1中规定了fprintf函数/8

F,F:表示浮点数的
double
参数被转换为
[−]ddd.ddd
,其中小数点字符后的位数等于精度规格。如果缺少精度,则将其视为
6

换句话说,这个程序:

#include <stdio.h>
int main() {
    double d1 = 11312.96, d2 = 11313.1;
    printf("%f\n%f\n", d1, d2);
    return 0;
}

如果希望它具有不同的格式(在看似不正确的情况下,以及在符合标准的情况下),请使用精度参数强制它,例如:

printf("%.2f\n", d1);    // gives "11312.96"
                          // posn:  123456789
                          //        ---------
printf("%9.2f\n", d1);    // gives " 11312.96"
printf("%9.2f\n", 3.1);   // gives "     3.10"
您可能还需要指定最小字段宽度,以确保数字在右侧对齐,例如:

printf("%.2f\n", d1);    // gives "11312.96"
                          // posn:  123456789
                          //        ---------
printf("%9.2f\n", d1);    // gives " 11312.96"
printf("%9.2f\n", 3.1);   // gives "     3.10"

如果您完全按照规定使用
%f
,这实际上违反了标准(这是不寻常的,但肯定不是闻所未闻的),该标准在
C11 7.21.6.1中规定了fprintf函数/8

F,F:表示浮点数的
double
参数被转换为
[−]ddd.ddd
,其中小数点字符后的位数等于精度规格。如果缺少精度,则将其视为
6

换句话说,这个程序:

#include <stdio.h>
int main() {
    double d1 = 11312.96, d2 = 11313.1;
    printf("%f\n%f\n", d1, d2);
    return 0;
}

如果希望它具有不同的格式(在看似不正确的情况下,以及在符合标准的情况下),请使用精度参数强制它,例如:

printf("%.2f\n", d1);    // gives "11312.96"
                          // posn:  123456789
                          //        ---------
printf("%9.2f\n", d1);    // gives " 11312.96"
printf("%9.2f\n", 3.1);   // gives "     3.10"
您可能还需要指定最小字段宽度,以确保数字在右侧对齐,例如:

printf("%.2f\n", d1);    // gives "11312.96"
                          // posn:  123456789
                          //        ---------
printf("%9.2f\n", d1);    // gives " 11312.96"
printf("%9.2f\n", 3.1);   // gives "     3.10"

如果需要固定数量的小数位数,则需要将其包含在格式说明符中,例如
%.2f
。请发布用于打印输出的代码。如果需要固定数量的小数位数,则需要将其包含在格式说明符中,例如
%.2f
。请发布用于打印输出的代码nt输出。请发布一条消息。sensorvalue实际上来自传感器设备的读数。它的数据类型是float。我只是怀疑传感器设备是否在不同的时间以不同的精度发送读数。当然,这听起来很奇怪。我知道如何指定其精度,如%.2f,但我只是不知道未来值的精度。这就是我使用“%f”的原因,我希望每次读取时显示的精度至少应该是相同的。@斯坦,是的,它应该是相同的。事实并非如此,这意味着您的C库有缺陷。但是,无论您是显式声明小数点后两位,还是允许隐式的六位(或者您的情况下的任意数字),您正在做出决定。您可以明确地执行此操作,并施加一些控制。sensorvalue实际上来自传感器设备的读数。它的数据类型是float。我只是怀疑传感器设备是否在不同的时间以不同的精度发送读数。当然,这听起来很奇怪。我知道如何指定其精度,如%.2f,但是我只是事先不知道即将到来的值的精度。这就是我使用“%f”的原因,我希望每次读取时至少显示的精度应该是相同的。@斯坦,是的,它应该是相同的。事实上,这并不意味着你的C库有缺陷。但是,无论你是显式地声明两位小数还是允许隐式的六位小数(或者在你的情况下是任意数字),你正在做决定。你最好明确地做,并施加一些控制。