strtof = strtod 后跟 cast?
strtof = strtod followed by cast?
假设您有一个字符串,如“0.1”,只能近似表示为二进制浮点数,并且您想将其转换为单精度浮点数。这可以作为
strtof(s, 0);
或
(float)strtod(s, 0);
直觉上,这些应该给出相同的结果,但是直觉在所有情况下都是正确的吗?或者是否存在任何边缘情况,在这种情况下,通过两次舍入,第二种形式给出的结果与第一种形式略有不同?
x86 FPU 始终使用 80 位浮点数,无论您使用何种类型。从 double
到 float
的转换甚至会产生额外的运行时成本。
我不确定,但是 strtof()
可以实现为 strtod()
的包装器,所以在你的地方我最好使用 strtof()
,而不是调用函数来解析double 然后转换为 float
,以表明您的意图。如果您不信任编译器并希望优化代码,那么使用 (float)strtod()
可能会在额外的 call/ret
指令上为您节省一点性能。
未指定 C 标准的 strtod
和 strtof
规范。它为 strtof
returns (float)strtod
总是、经常或从不的可能性留有余地。 (This paragraph refers to another section of the standard that contains that paragraph,表示“结果是最近的可表示值,或者是与最近的可表示值紧邻的更大或更小的可表示值,以实现定义的方式选择”)。
典型实现strtod
和strtof
return分别是最近的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
.
假设您有一个字符串,如“0.1”,只能近似表示为二进制浮点数,并且您想将其转换为单精度浮点数。这可以作为
strtof(s, 0);
或
(float)strtod(s, 0);
直觉上,这些应该给出相同的结果,但是直觉在所有情况下都是正确的吗?或者是否存在任何边缘情况,在这种情况下,通过两次舍入,第二种形式给出的结果与第一种形式略有不同?
x86 FPU 始终使用 80 位浮点数,无论您使用何种类型。从 double
到 float
的转换甚至会产生额外的运行时成本。
我不确定,但是 strtof()
可以实现为 strtod()
的包装器,所以在你的地方我最好使用 strtof()
,而不是调用函数来解析double 然后转换为 float
,以表明您的意图。如果您不信任编译器并希望优化代码,那么使用 (float)strtod()
可能会在额外的 call/ret
指令上为您节省一点性能。
未指定 C 标准的 strtod
和 strtof
规范。它为 strtof
returns (float)strtod
总是、经常或从不的可能性留有余地。 (This paragraph refers to another section of the standard that contains that paragraph,表示“结果是最近的可表示值,或者是与最近的可表示值紧邻的更大或更小的可表示值,以实现定义的方式选择”)。
典型实现strtod
和strtof
return分别是最近的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
.