为什么FLT_MAX和FLT_MIN不是正的和负的无穷大,它们的用途是什么?

时间:2011-11-01 22:29:11

标签: c++ c

从逻辑上讲,鉴于浮点值的性质,float的最大和最小可表示值分别为正和负无穷大。

为什么FLT_MAXFLT_MIN没有设置?我知道这是“标准要求的方式”。但是, 使用的内容可以FLT_MAXFLT_MIN,因为它们目前位于float 的可表示数字范围的中间位置?其他数字限制具有一些实用性,因为它们保证了比较(例如“No INT可以测试大于INT_MAX”)。没有这种保证,这些浮动限制有什么用?

C ++的一个激励范例:

#include <vector>
#include <limits>

template<typename T>
T find_min(const std::vector<T> &vec)
{
    T result = std::numeric_limits<T>::max();
    for (std::vector<T>::const_iterator p = vec.start() ; p != vec.end() ; ++p)
        if (*p < result) result = *p;
    return result;
}

如果T是整数类型,则此代码可以正常工作,但如果它是浮点类型则不行。这很烦人。 (是的,标准库提供了min_element,但这不是重点。重点是模式。)

4 个答案:

答案 0 :(得分:16)

FLT_MAX在第5.2.4.2.2(9)节中定义为

  

最大可表示的有限浮点数

正无穷大不是有限的。

FLT_MIN在第5.2.4.2.2(10)节中定义为

  

最小归一化正浮点数

负无穷大既不正常也不正面。

答案 1 :(得分:15)

FLT_MIN / MAX的目的是告诉您最小和最大可表示的浮点数字是什么。无限不是一个数字;这是一个限制。

  

FLT_MAX或FLT_MIN有什么用途,因为它们目前位于浮动的可表示数值范围的中间?

它们不在中间或可表示的范围内。没有正浮点值x,您可以将其添加到FLT_MAX并获得可表示的数字。你会得到+ INF。

  

如果T是整数类型,则此代码可以正常工作,但如果它是浮点类型则不行。这很烦人。 (是的,标准库提供min_element,但这不是重点。重点是模式。)

它怎么不“工作正常?”它为您提供最小的价值。唯一不能“正常工作”的情况是表格中只包含 + INF。即使在这种情况下,它也会返回一个实际的数字,而不是错误代码。无论如何,这可能是更好的选择。

答案 2 :(得分:8)

我想说你看到的破碎模式只是C中差命名的工件,而在带有numeric_limits和模板的C ++中,它是一个破坏模板的实际语义缺陷想要处理整数和浮点值的代码。当然,你可以编写一些额外的代码来测试你是否有整数或浮点类型(例如if ((T)1/2) /* floating point */ else /* integer */)并且问题消失了。

至于为什么有人会关心FLT_MINFLT_MAX给你的价值,它们对于避免下溢和溢出很有用。例如,假设我需要计算sqrt(x²-1)。对于大于或等于1的任何浮点x,这是明确定义的,但是当x很大时,执行平方,减法和平方根很容易溢出并使结果无意义。有人可能想测试x > FLT_MAX/x是否以其他方式处理此案例(例如简单地返回x: - )。

答案 3 :(得分:6)

与整数类型不同,浮点类型(几乎?)普遍对称为零,我认为C浮点模型需要这个。

在二重补充系统(即几乎所有现代系统)上,INT_MIN-INT_MAX-1;在其他系统上,它可能是-INT_MAX。 (Qibble:如果将最低可表示值视为陷阱表示,则二进制补码系统可以使INT_MIN等于-INT_MAX。)因此INT_MIN传达INT_MAX的信息本身没有。

最小正值的宏不会特别有用;这只是1。

另一方面,在浮点数中,幅度最大的负值仅为-FLT_MAX(或-DBL_MAX-LDBL_MAX)。

至于为什么它们不是Infinity,已经有了一种表示无限值的方法(至少在C99中):宏INFINITY。这可能会导致某些C ++应用程序出现问题,但这些应用程序是为C语言定义的,它没有std::numeric_limits<T>::max()之类的内容。

此外,并非所有浮点系统都具有无穷大(或NaN)的表示。

如果FLT_MAXINFINITY(在支持它的系统上),则可能需要另一个宏来表示最大的可表示实际值。