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

strtof(s, 0);

或者
(float)strtod(s, 0);

从直觉上讲,这些应该给出相同的结果,但是直觉在所有情况下都是正确的吗?还是在某些边缘情况下,第二种形式经过两次舍入后得出的结果与第一种形式略有不同?

最佳答案

C标准的strtodstrtof规范未指定。这为strtof始终,非常频繁或从不返回(float)strtod留下了空间。 (This paragraph指的是包含that paragraph的标准的另一部分,其中说:“结果是以实现定义的方式选择的最接近的可表示值,或者紧邻最接近的可表示值的较大或较小的可表示值”)。
strtodstrtof典型实现分别将最接近的double和最接近的float返回到传递给它们的十进制表示形式。当这些函数以这种方式运行时,strtof(s, 0)几乎总是(float)strtod(s, 0)相同。十进制表示形式不一致的十进制表示形式表示为double-rounding problem,因为首先将十进制表示形式四舍五入到double然后再四舍五入到float会产生与直接四舍五入到float不同的结果。请注意,发生这种情况时,strtof结果是更精确的结果。中间舍入使误差略大于ULP的一半,而不是略小于ULP的一半。

在转换为double之前通过float时,带有双舍入问题的十进制表示形式的一个示例是1.01161128282547(取自this quiz)。最近的double恰好位于两个float之间。直接舍入到float会得到最接近的float,而经过最接近的double则会产生另一个float

10-04 22:00
查看更多