为什么FLT_MAX和FLT_MIN不是正的和负的无穷大,它们的用途是什么?
从逻辑上讲,考虑到浮点值的性质,浮点数的最大和最小可表示值分别为正和负无穷大。
那么,为什么FLT_MAX
和FLT_MIN
没有设置为它们? 我知道这是“标准要求的方式”。 但是, FLT_MAX
或FLT_MIN
有什么用途 ,因为它们目前位于float
的可表示数值范围的中间 ? 其他数字限制具有一些实用性,因为它们保证了比较(例如“无INT可以测试大于INT_MAX”)。 没有这种保证,这些浮动限制有什么用?
C ++的一个激励示例:
#include #include template T find_min(const std::vector &vec) { T result = std::numeric_limits::max(); for (std::vector::const_iterator p = vec.start() ; p != vec.end() ; ++p) if (*p < result) result = *p; return result; }
如果T是整数类型,则此代码可以正常工作,但如果它是浮点类型则不行。 这很烦人。 (是的,标准库提供min_element
,但这不是重点。重点是模式 。)
FLT_MIN
/ MAX
的目的是告诉您最小和最大可表示的浮点数是多少。 无限不是一个数字; 这是一个限制。
FLT_MAX或FLT_MIN有什么用途,因为它们目前位于float的可表示数值范围的中间?
它们不位于中间或可表示的范围内。 没有正浮点值x
,您可以将其添加到FLT_MAX
并获得可表示的数字。 你会得到+ INF。
如果T是整数类型,则此代码可以正常工作,但如果它是浮点类型则不行。 这很烦人。 (是的,标准库提供min_element,但这不是重点。重点是模式。)
怎么不“工作正常?” 它为您提供最小的价值。 唯一不能“正常工作”的情况是表格只包含+ INF。 即使在这种情况下,它也会返回一个实际数字 ,而不是错误代码。 无论如何,这可能是更好的选择。
FLT_MAX
在FLT_MAX
(9)节中定义为
最大可表示的有限浮点数
正无穷大不是有限的。
FLT_MIN
在FLT_MIN
(10)节中定义为
最小归一化正浮点数
负无穷大既不正常也不正。
我会说你看到的破碎模式只是C中命名不佳的人工制品,而在带有numeric_limits
和模板的C ++中,它是一个实际的语义缺陷,它破坏了想要处理整数和浮点值的模板代码。 当然你可以编写一些额外的代码来测试你是否有整数或浮点类型(例如if ((T)1/2) /* floating point */ else /* integer */
)并且问题是远。
至于为什么有人会关心FLT_MIN
和FLT_MAX
给你的值,它们对于避免下溢和溢出很有用。 例如,假设我需要计算sqrt(x²-1)
。 这对于任何大于或等于1的浮点x
都是明确定义的,但是当x
很大时,执行平方,减法和平方根很容易溢出并使结果无意义。 有人可能想测试x > FLT_MAX/x
是否以其他方式处理这种情况(例如简单地返回x
:-)。
与整数类型不同,浮点类型(几乎?)普遍对称为零,我认为C浮点模型需要这个。
在二进制补码系统(即几乎所有现代系统)上, INT_MIN
是-INT_MAX-1
; 在其他系统上,它可能是-INT_MAX
。 (Qibble:如果最低可表示值被视为陷阱表示,则二进制补码系统可以使INT_MIN
等于-INT_MAX
。)因此INT_MIN
传达INT_MAX
本身不会传递的信息。
最小正值的宏不会特别有用; 那只是1。
另一方面,在浮点中,具有最大幅度的负值仅为-FLT_MAX
(或-DBL_MAX
,或-LDBL_MAX
)。
至于为什么它们不是无限,已经有了一种表示无限值的方法(至少在C99中):宏无限。 这可能会导致某些C ++应用程序出现问题,但这些应用程序是为C定义的,它没有像std::numeric_limits
。
此外,并非所有浮点系统都具有无穷大(或NaN)的表示。
如果FLT_MAX
是INFINITY
(在支持它的系统上),则可能需要另一个宏来表示最大的可表示实际值。