strtof = strtod 后跟 cast?

strtof = strtod followed by cast?

假设您有一个字符串,如“0.1”,只能近似表示为二进制浮点数,并且您想将其转换为单精度浮点数。这可以作为

strtof(s, 0);

(float)strtod(s, 0);

直觉上,这些应该给出相同的结果,但是直觉在所有情况下都是正确的吗?或者是否存在任何边缘情况,在这种情况下,通过两次舍入,第二种形式给出的结果与第一种形式略有不同?

x86 FPU 始终使用 80 位浮点数,无论您使用何种类型。从 doublefloat 的转换甚至会产生额外的运行时成本。

我不确定,但是 strtof() 可以实现为 strtod() 的包装器,所以在你的地方我最好使用 strtof(),而不是调用函数来解析double 然后转换为 float,以表明您的意图。如果您不信任编译器并希望优化代码,那么使用 (float)strtod() 可能会在额外的 call/ret 指令上为您节省一点性能。

未指定 C 标准的 strtodstrtof 规范。它为 strtof returns (float)strtod 总是、经常或从不的可能性留有余地。 (This paragraph refers to another section of the standard that contains that paragraph,表示“结果是最近的可表示值,或者是与最近的可表示值紧邻的更大或更小的可表示值,以实现定义的方式选择”)。

典型实现strtodstrtofreturn分别是最近的double和最近的float 传递给他们的十进制表示。当这些函数以这种方式运行时,那么 strtof(s, 0) 几乎总是(float)strtod(s, 0) 相同。不相同的十进制表示表示为 double-rounding problem,因为首先将十进制表示四舍五入为 double,然后四舍五入为 float 与直接四舍五入为 [=] 产生的结果不同17=]。请注意,发生这种情况时,strtof 结果更为准确。中间舍入使误差略大于 ULP 的一半,而不是略小于 ULP 的一半。

在转换为 float 之前经过 double 时出现双舍入问题的小数表示法的一个示例是 1.01161128282547(取自 this quiz)。最近的 double 恰好在两个 float 的中间。直接四舍五入到 float 得到最近的 float,通过最近的 double 得到另一个 float.