在C中解析csv文件时丢失双精度



我正在尝试用以下格式读取c中的文件:

6.43706064058,4.15417249035
3.43706064058,1.15417249035
...

我能够解析出两个双精度数,但是当我打印出我所解析的内容时,我注意到我只能得到小数点后6位。下面是我的代码:

long double d1;
long double d2;
fscanf(file, "%Lf,%Lf", &d1, &d2);
printf("x:%Lf, y:%Lf", d1, d2);
输出:

x:6.437061, y:4.154172
...

我在哪里失去了精度?是否有可能它被正确读取,但我的printf语句没有显示所有的精度?

是否有可能它被正确读取,但我的printf语句没有显示所有的精度?

事情就是这样。来自printf(3)手册页:

…后的位数小数点字符等于精度规范。如果缺少精度,则取6…

告诉printf通过改变格式字符串来显示更精确的内容:

 printf("x:%.11Lf, y:%.11Lf", d1, d2);

默认的%f格式只打印小数点后6位,这给你的精度远低于实际的浮点值(除非指数很大),可能根本没有精度(如果指数大于略负)。除非你知道你所有的值都离零有界(例如所有大于1),你真的需要使用%g格式(可以根据需要切换到指数表示法)或%e格式(总是使用指数表示法)以保持其精度的方式打印浮点值。

还需要使用足够多的小数点。对于IEEE双精度,小数点后17位就足够了,因此%.17g将是首选格式。对于long double,它取决于特定实现中使用的类型。值得庆幸的是,C语言提供了一个宏DECIMAL_DIG,它可以精确地提供所需的位置数量。所以你可以使用:

printf("%.*Lg", DECIMAL_DIG, x);

或类似。注意,这将打印比输入文件中最初显示的更多的位置。如果您知道您的输入总是有特定数量的位置,您可能只是硬编码,而不是使用DECIMAL_DIG来获得更统一的输出。

您没有达到您想要的精度的原因是因为数字中的间距级别不够。在第一个数字6.43706064058中,您有13个数字,包括小数点,因此您可以输入

    printf("x:%13Lf, y:%Lf", d1, d2);

允许x:

有13个空格

表示第二个数字4.15417249035,你也有13,所以你要输入

    printf("x:%13Lf, y:13%Lf", d1, d2);

,然后输出:

    x:6.43706064058, y:4.15417249035

在执行printf函数时,必须为数字中的所有空格留出空间。希望这对你有所帮助!

最新更新