gpt4 book ai didi

c++ - 在 C++ 中使用 floor 函数的舍入误差

转载 作者:太空宇宙 更新时间:2023-11-03 10:26:01 26 4
gpt4 key购买 nike

有人问我以下代码的输出是什么:

floor((0.7+0.6)*10);

它返回 12。

我知道浮点表示法不允许以无限精度表示所有数字,我应该预料到会出现一些差异。

我的问题是:

  1. 我怎么知道这段代码返回的是 12,而不是 13?为什么 (0.7+0.6)*10 比 13 一点,而不是一点?

  2. floor 函数什么时候可以正常工作,什么时候可以正常工作?

注意:我不是在问 float 表示形式如何或为什么输出不完全是 13。我想知道我应该如何推断 (0.7+0.6)*10 有点 大于 13。

最佳答案

How should I know that this piece of code returns 12, not 13? Why is (0.7+0.6)*10 a bit less than 13, not a bit more?

假设您的编译平台严格使用 IEEE 754 标准格式和操作。然后,将所有涉及的常数转换为二进制,保留 53 位有效数字,并应用 IEEE 754 中定义的基本运算,通过计算数学结果并在每一步舍入到 53 位有效二进制数字。任何阶段都不需要计算机参与,但使用 C99 的十六进制浮点格式输入和输出可以让您的生活更轻松。

When can I expect the floor function to work incorrectly and when it works correctly for sure?

floor() 对所有正参数都是精确的。它在您的示例中正常工作。让您感到惊讶的行为并非源自 floor,也与 floor 无关。令人惊讶的行为始于 6/10 和 7/10 不能完全表示为二进制浮点值这一事实,并且由于这些值具有长扩展,浮点运算 +* 可以产生一个稍微四舍五入的结果 wrt 你可以从它们实际应用的参数中期望的数学结果。 floor() 是您的代码中唯一不涉及近似值的地方。

查看发生了什么的示例程序:

#include <stdio.h>
#include <math.h>

int main(void) {
printf("%a\n%a\n%a\n%a\n%a\n",
0.7,
0.6,
0.7 + 0.6,
(0.7+0.6)*10,
floor((0.7+0.6)*10));
}

结果:

0x1.6666666666666p-10x1.3333333333333p-10x1.4ccccccccccccp+00x1.9ffffffffffffp+30x1.8p+3

IEEE 754 double 实际上是针对二进制定义的,但为了简洁起见,有效数以十六进制表示。 p 之后的指数表示 2 的幂。例如,最后两个结果都是 *2 3 的形式。

0x1.8p+3 是 12。下一个整数 13 是 0x1.ap+3,但是计算没有完全达到那个值,所以floor() 的行为是向下舍入到 12。

关于c++ - 在 C++ 中使用 floor 函数的舍入误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35132573/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com