C++ 为什么可以';我们不能从浮点最大值中减去吗?

C++ 为什么可以';我们不能从浮点最大值中减去吗?,c++,floating-point,C++,Floating Point,几天前,我试图从std::numeric\u limits::max()中减去10000,我刚刚发现,无论减去什么值,该值都没有改变。事实上,似乎所有浮点类型都有这种行为 例如(在g++和msvc上),这个不通过(好): int i=std::numeric_limits::max(); 断言(i==i-10000);//没有通过 但这一个有(?): float f=std::numeric_limits::max(); 断言(f==f-10000.f);//通过 我甚至尝试直接分配最大值(

几天前,我试图从
std::numeric\u limits::max()
中减去10000,我刚刚发现,无论减去什么值,该值都没有改变。事实上,似乎所有浮点类型都有这种行为

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

int i=std::numeric_limits::max();
断言(i==i-10000);//没有通过
但这一个有(?):

float f=std::numeric_limits::max();
断言(f==f-10000.f);//通过

我甚至尝试直接分配最大值(在本例中为3.40282e+38),但它似乎没有改变任何东西。而且,它似乎对任何足够高的值都能做完全相同的事情。有人能给我解释一下为什么会这样吗?谢谢。

浮点数不像
int
那样精确。你减去的量太小了,不能对结果产生影响,只是在精度上丢失了<代码>标准::数值限制::max()非常大(3.402823e+38)

如果您这样做:

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

我确信它会失败。

您已经达到了IEEE_754浮点表示的极限。10000.0与最大浮点数相比非常小,因此该值将四舍五入到
std::numeric\u limits::max()


查看另一个答案()中的示例以了解更多详细信息。

您可以从该值中很好地减去,但是减去1不足以得到下一个较低的浮点值。出现断言是因为整数值比原始值小10000(即不同)。但是对于浮点值,即使是很好的减法似乎也不会改变任何东西。在这里,我减去10000,但它不会改变任何东西(我更新了问题)。“无论我减去了什么值”胡说八道。尝试减去相同数量级的值。当然,16位数字的第50位的变化并没有什么区别。@Jérémipanenton浮点的精度与其大小有关。最大浮点值(根据维基百科,为3.402823×10^38)。浮点数只有23位可用于精度,因此,如果这23位用于如此大的值的精度,-10000不会改变这些精度位的值。
float f = std::numeric_limits<float>::max();
assert(f == f - 10000.f); // Pass
float f = std::numeric_limits<float>::max();
assert(f == f - f/2.f);