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

ten*_*our 15 c c++

从逻辑上讲,给定浮点值的性质,a的最大和最小可表示值float分别为正和负无穷大.

那么,为什么FLT_MAXFLT_MIN不是他们呢?我知道这是"标准要求的方式".但是,它们可以或者具有什么用途,因为它们目前位于可表示的数值范围的中间FLT_MAXFLT_MINfloat?其他数字限制具有一些实用性,因为它们保证了比较(例如"无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;
}
Run Code Online (Sandbox Code Playgroud)

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

Ray*_*hen 17

FLT_MAX 在5.2.4.2.2(9)节中定义为

最大可表示的有限浮点数

正无穷大不是有限的.

FLT_MIN 在5.2.4.2.2(10)节中定义为

最小归一化正浮点数

负无穷大既不正常也不正.

  • 为了知道你的计算将在什么时候崩溃. (9认同)
  • FLT_MAX和FLT_MIN比+ -inf更有用,你知道后者是什么.可以说这些名字并不完美,但价值观是人们需要知道的. (8认同)
  • 大多数人只是交叉手指,希望"FLT_MIN"和"FLT_MAX"令人满意.我想你可能会写`if(v <FLT_MIN*2)错误("危险接近下溢,结果不值得信赖");`但是由于大多数实现已经确定了IEEE格式,因此`FLT_MIN`和`FLT_MAX`的值是现在几乎常量,所以你可以预先计算你的计算而不必进行动态检查.将它们设置为+ Inf和-Inf并不能真正告诉你很多关于`float`类型的有意义范围. (2认同)

Nic*_*las 16

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

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

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

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

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

  • @Quuxplusone:[Infinity*不是*数字](https://en.wikipedia.org/wiki/Infinity). (6认同)
  • 这是MAX的合理解释,但积分MIN和浮点MIN之间的差异仍然很大. (3认同)
  • 倾向于声明"无限不是数字"并将+ INF描述为"错误代码". (3认同)

R..*_*R.. 8

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

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

  • 好的答案.虽然我想我会选择`std :: max(std :: numeric_limits <T> :: infinity(),std :: numeric_limits <T> :: max()`.你永远不知道`T`是否是自定义的定点表示或某事:-) (2认同)

Kei*_*son 7

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

在二进制补充系统(即几乎所有现代系统)上,INT_MIN-INT_MAX-1; 在其他系统上,它可能是-INT_MAX.(狡辩:如果将最低可表示的值视为陷阱表示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(在支持它的系统上),那么就可能需要对可表示的最大实际价值另一个宏.

  • @Nemo:有;它称为“ HUGE_VAL”(或“ HUGE_VALF”或“ HUGE_VALL”)。 (2认同)