将字符串转换为双精度等于文字双精度?

时间:2018-04-02 16:15:07

标签: c

例如:

assert(atof("1.2") == 1.2);

无论使用什么浮点数?

据我所知,浮点精度并不准确,但它精确到不精确,所以二进制的舍入产生完全相同的双精度?

3 个答案:

答案 0 :(得分:29)

C标准无法保证这一点。在源代码中转换浮点文字的语义在C 2011 [draft N1570] 6.4.4.2中规定。这表示推荐但不是必需的做法是浮点常量的转换时转换应该与库函数(如strtod)对字符串的执行时转换相匹配。

更重要的是,该标准甚至不要求具有相同数学值的两个不同文字(例如1.231.230)转换为相同的值。这些示例来自标准中的脚注75,该脚注是段落的脚注,表示同一源形式的所有浮点常量应转换为相同的值。因此,1.23始终会转换为源中显示的相同值,但1.230不一定转换为与1.23123e-2相同的值。即使123e-2123e-02也可能不同。

7.22.1.2中指定的

atof(p)等同于strtod(p, (char **) NULL),除了它们如何处理错误。 strtod在7.22.1.3中指定。该子句有一些推荐的准确性做法,但对于匹配文字的翻译时转换没有提及。

答案 1 :(得分:1)

此检查将不可避免地取决于实现,因此我编写了以下小测试脚本:

#include <stdio.h>
#include <stdlib.h>

int main()
  {
  double d1 = 1.2;
  double d2 = atof("1.2");
  char *p;
  double d3 = strtod("1.2", &p);

  printf("d1 = %40.40f\n", d1);
  printf("d2 = %40.40f\n", d2);
  printf("d3 = %40.40f\n", d3);

  if(d1 != d2)
    printf("d1 != d2\n");

  if(d2 != d3)
    printf("d2 != d3\n");
  }

对于HP C / C ++编译器,版本A.06.25.02,此输出

d1 = 1.1999999999999999555910790149937383800000
d2 = 1.1999999999999999555910790149937383800000
d3 = 1.1999999999999999555910790149937383800000

表明编译器执行的转换(至少1.2)与atofstrtod执行的转换相匹配。

答案 2 :(得分:-5)

在军事工程中,我们总是通过在真实的浮动比较值周围放置一个公差带+/- 0.000001来解决这个问题。通过这种方式,您可以了解您真正要比较的内容并帮助防止污染算法的设计目标。在处理浮点数时,人们总是使用模糊数字,而不能进行硬比较。