sscanf的精度问题

Precision issue with sscanf

本文关键字:问题 精度 sscanf      更新时间:2023-10-16

我正在使用sscanf从文本文件中读取一些值,并使用%lf将它们存储为double。

,但值被四舍五入。例如

读取:5.655035220-E02存储内容:0.0565504

我认为这与格式说明符"%lf"有关。

请建议正确的格式说明符读取和存储值,因为它是。

你的意思是你已经写了这样的代码(感谢下次提供你的代码,顺便说一下,它真的有助于理解发生了什么,而不是不得不依赖模糊的线索):

#include <stdio.h>
int main(){
  double v2;
  sscanf("5.655035220e-02", "%lf", &v2);
  printf("%fn", v2);
  return 0;
}

得到如下结果:

0.056550

(给出或取一个十进制数字)

您的问题不在sscanf()的十进制到双进位转换中,这很好,而是在printf()的双进位到十进制转换中。变量v2包含一个很好的近似你扫描的数字。您只是不要求printf()打印这个近似值的许多数字。试一试:

printf("%.10fn", v2);
0.0565503522

你有两个问题

您的printf()说明符舍入了太多位
(可能)您的浮点变量无法保留所有所需的精度。

建议格式说明符:
阅读:sscanf(buffer, "%le", &d)
存储:printf("%.*le", DECIMAL_DIG /* or DBL_DIG+3 */, d)


问题1

double d;
sscanf("5.655035220e-02", "%lf", &d);
printf("%.7lfn", d);  // 0.0565504
printf("%.7len", d);  // 5.6550352e-02
printf("%.9len", d);  // 5.655035220e-02

如果你使用%e打印出来,它们会比%f的前导零数字更有意义。你看到的数字是一个四舍五入的值。这是不是存储的数字5.65503522000000008…e-02


问题2

如果您使用类型float而不是double,您可能会遇到精度损失,因为5.655035220e-02是典型的4字节浮点数5.65503537...e-02


推荐@devnull关于阅读每个计算机科学家应该知道的浮点算术的想法。http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

看一下这段代码,

double tt=  5.655035220e-02;
printf("%le",tt);
getchar();

解决方案与IAM HERE的帖子相同。问题是,你写的值为5.6…20- 02,但应该是5.6…