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

时间:2021-06-03 22:33:20

For example:

例如:

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

regardless of what float is used?

不管使用什么浮点数?

I understand that the floating point precision isn't exact, but it is precisely inexact so does the rounding to binary produce the exact same double?

我知道浮点精度不是精确的,但是它是精确的,那么四舍五入到二进制是否会产生相同的双精度呢?

3 个解决方案

#1


29  

This is not guaranteed by the C standard. The semantics of converting a floating-point literal in the source code are specified in C 2011 [draft N1570] 6.4.4.2. This says the recommended, but not required, practice is that the translation-time conversion of floating-point constants should match the execution-time conversion of character strings by library functions, such as strtod.

这不是C标准的保证。在源代码中转换浮点字面值的语义在C 2011[草案N1570] 6.4.4.2中被指定。这说明推荐的(但不是必需的)实践是,浮点常量的平移-时间转换应该与库函数(如strtod)对字符字符串的执行-时间转换相匹配。

More than that, the standard does not even require that two different literals with the same mathematical value, such as 1.23 and 1.230, convert to the same value. These examples come from footnote 75 in the standard, which is a footnote to a paragraph stating that all floating-point constants of the same source form shall convert to the same value. Thus, 1.23 always converts to the same value wherever it appears in the source, but 1.230 does not necessarily convert to the same value as 1.23 or 123e-2. Even 123e-2 and 123e-02 may be different.

此外,该标准甚至不要求两个具有相同数学值的不同文字(如1.23和1.230)转换为相同的值。这些例子来自标准的脚注75,它是一段的脚注,说明同一来源形式的所有浮点常量都应转换为相同的值。因此,在源文件中出现的地方,1.23总是转换为相同的值,但是1.230不一定转换为与1.23或123e-2相同的值。即使是123e-2和123e-02也可能不同。

atof(p) is specified in 7.22.1.2 to be equivalent to strtod(p, (char **) NULL) except for how they behave with errors. strtod is specified in 7.22.1.3. That clause has some recommended practices for accuracy but is silent about matching the translation-time conversion of literals.

atof(p)在7.22.1.2中被指定为等价于strtod(p, (char **) NULL),除了它们处理错误的方式。7.22.1.3中指定了strtod。该子句有一些关于准确性的推荐实践,但是对于匹配文本的翻译时间转换,它保持沉默。

#2


1  

This check will inevitably be implementation-dependent, so I've written the following little test script:

这个检查不可避免地是依赖于实现的,所以我写了下面的小测试脚本:

#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");
  }

In the case of the HP C/C++ compiler, version A.06.25.02, this outputs

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

d1 = 1.1999999999999999555910790149937383800000
d2 = 1.1999999999999999555910790149937383800000
d3 = 1.1999999999999999555910790149937383800000

which demonstrates that the conversion (of 1.2, at least) which is performed by the compiler matches the conversions performed by atof and strtod.

这说明编译器执行的转换(至少是1.2)与atof和strtod执行的转换相匹配。

#3


-4  

From Military engineering we always account for this issue by placing a tolerance band say +/- 0.000001 around the true float comparison value. This way you know what you are truly comparing and help prevent polluting what the algorithm is designed to do. One is always working with fuzzy numbers when working with floating point numbers where one can't or should not do a hard comparison on.

在军事工程中,我们总是通过在真正的浮点比较值周围放置一个公差范围,比如+/- 0.000001。这样你就知道你真正在比较什么,并帮助防止污染算法的设计。当处理浮点数时,一个人总是在处理模糊数,而不能或不应该做一个比较。

#1


29  

This is not guaranteed by the C standard. The semantics of converting a floating-point literal in the source code are specified in C 2011 [draft N1570] 6.4.4.2. This says the recommended, but not required, practice is that the translation-time conversion of floating-point constants should match the execution-time conversion of character strings by library functions, such as strtod.

这不是C标准的保证。在源代码中转换浮点字面值的语义在C 2011[草案N1570] 6.4.4.2中被指定。这说明推荐的(但不是必需的)实践是,浮点常量的平移-时间转换应该与库函数(如strtod)对字符字符串的执行-时间转换相匹配。

More than that, the standard does not even require that two different literals with the same mathematical value, such as 1.23 and 1.230, convert to the same value. These examples come from footnote 75 in the standard, which is a footnote to a paragraph stating that all floating-point constants of the same source form shall convert to the same value. Thus, 1.23 always converts to the same value wherever it appears in the source, but 1.230 does not necessarily convert to the same value as 1.23 or 123e-2. Even 123e-2 and 123e-02 may be different.

此外,该标准甚至不要求两个具有相同数学值的不同文字(如1.23和1.230)转换为相同的值。这些例子来自标准的脚注75,它是一段的脚注,说明同一来源形式的所有浮点常量都应转换为相同的值。因此,在源文件中出现的地方,1.23总是转换为相同的值,但是1.230不一定转换为与1.23或123e-2相同的值。即使是123e-2和123e-02也可能不同。

atof(p) is specified in 7.22.1.2 to be equivalent to strtod(p, (char **) NULL) except for how they behave with errors. strtod is specified in 7.22.1.3. That clause has some recommended practices for accuracy but is silent about matching the translation-time conversion of literals.

atof(p)在7.22.1.2中被指定为等价于strtod(p, (char **) NULL),除了它们处理错误的方式。7.22.1.3中指定了strtod。该子句有一些关于准确性的推荐实践,但是对于匹配文本的翻译时间转换,它保持沉默。

#2


1  

This check will inevitably be implementation-dependent, so I've written the following little test script:

这个检查不可避免地是依赖于实现的,所以我写了下面的小测试脚本:

#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");
  }

In the case of the HP C/C++ compiler, version A.06.25.02, this outputs

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

d1 = 1.1999999999999999555910790149937383800000
d2 = 1.1999999999999999555910790149937383800000
d3 = 1.1999999999999999555910790149937383800000

which demonstrates that the conversion (of 1.2, at least) which is performed by the compiler matches the conversions performed by atof and strtod.

这说明编译器执行的转换(至少是1.2)与atof和strtod执行的转换相匹配。

#3


-4  

From Military engineering we always account for this issue by placing a tolerance band say +/- 0.000001 around the true float comparison value. This way you know what you are truly comparing and help prevent polluting what the algorithm is designed to do. One is always working with fuzzy numbers when working with floating point numbers where one can't or should not do a hard comparison on.

在军事工程中,我们总是通过在真正的浮点比较值周围放置一个公差范围,比如+/- 0.000001。这样你就知道你真正在比较什么,并帮助防止污染算法的设计。当处理浮点数时,一个人总是在处理模糊数,而不能或不应该做一个比较。