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

时间:2013-04-28 02:28:48

标签: c types scanf

我正在尝试使用以下格式读取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语句没有显示所有精度?

3 个答案:

答案 0 :(得分:4)

  

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

这正是发生的事情。来自printf(3) man page

  

...之后的位数                小数点字符等于精度规范。                如果缺少精度,则将其视为6 ...

通过更改格式字符串告诉printf显示更高的精度:

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

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:0)

你没有达到你想要的精确度的原因是因为数量的间距水平不够。在第一个数字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功能时,必须为数字内的所有空格留出空间。 希望有所帮助!