为什么我们不能从浮点最大值中减去?

Why can't we subtract from floating point maximum values?

本文关键字:最大值 我们 不能 为什么      更新时间:2023-10-16

几天前,我试图从 std::numeric_limits<float>::max()中减去10000,而我只是发现该值根本没有变化,无论我要减去什么值。实际上,似乎所有浮点类型都有这种行为。

例如(在g 和msvc上),这个不通过(好):

int i = std::numeric_limits<int>::max();
assert(i == i - 10000); // Doesn't pass

但这是(?):

float f = std::numeric_limits<float>::max();
assert(f == f - 10000.f); // Pass

我什至尝试直接分配最大值(在这种情况下为3.40282e 38),但似乎并没有改变任何内容。同样,它似乎在任何足够高的值的情况下完成了完全相同的事情。有人可以向我解释为什么这样做?谢谢。

浮点数不像int那样精确。您减去的数量太小了,无法在显着范围内产生影响,并且精确地损失了。std::numeric_limits<float>::max()是疯狂的(3.402823e 38)。

如果您这样做:

float f = std::numeric_limits<float>::max();
assert(f == f - f/2.f);

我确定它会失败。

您正在击中IEEE_754浮点表示的限制。与最大浮点数相比,10000.0是如此之小,以至于该值被舍入 std::numeric_limits<float>::max()

检查其他答案中的示例(浮点数学损坏吗?)以获取其他细节。