13

numeric_limits 特征应该是获取各种类型信息的通用方法,以便能够执行以下操作

template<typename T>
T min(const std::vector<T>& vect)
{
    T val = std::numeric_limits<T>::min();

    for(int i=0 ; i<vect.size() ; i++)
        val = max(T, vect[i]);

    return val;
}

问题是(至少使用 MS Visual Studio 2008) numeric_limits<int>::min() 返回最小的负数,而 numeric_limits<double>::min() 返回最小的数!

有人知道这种设计背后的原理吗?有没有更好的(推荐的?)使用 numeric_limits 的方法?在我上面的特定函数中,我当然可以将 T 初始化为 vect[0],但这不是我要寻找的答案..

另请参阅此处的(浮点特定)讨论

4

7 回答 7

9

您可以使用 Boost 库。Numeric Conversions 库提供了一个可以一致使用的称为边界的类。

请参阅此处的文档。

于 2009-04-29T08:43:08.280 回答
6

这是一个旧线程,但有一个更新的答案:

C++11 添加了一个lowest()函数std::numeric_limits见这里

因此,您现在可以调用std::numeric_limits<double>::lowest()以获取可表示的最低负值。

于 2013-02-20T18:27:40.117 回答
4

min() 的行为并不奇怪,它返回FLT_MIN, DBL_MINor INT_MIN(或它们各自的值),具体取决于您专门研究的类型。所以你的问题应该是为什么FLT_MINDBL_MIN定义不同INT_MIN

不幸的是,我不知道后一个问题的答案。

我怀疑它是出于实际目的而定义的。对于整数,您通常关心上溢/下溢,其中最小值和最大值变得重要。

对于浮点数,存在一种不同类型的下溢,因为计算可能导致大于零但小于该浮点类型的最小可表示小数的值。知道最小的可表示浮点值可以让您解决这个问题。另请参阅关于次正规/非正规数的 Wikipedia 文章。

于 2009-04-29T08:52:51.707 回答
1

我不确定理由,但这是预期的行为。好吧,从某种意义上说,这就是 Josuttis(并且可能是标准)描述它的方式!

min():“最小有限值(具有非规范化的浮点类型的最小规范化值)。”

尽我所能判断该类型是否不是整数 ( numeric_limits<>::is_integer) 并且具有非规范化 ( numeric_limits<>::has_denorm)min()将返回该类型的最小可表示值。否则它将返回最小值-这可能是负数。

要获得更一致的界面,请查看Boost numeric/conversion库。特别是bounds特征类。这是一个片段:

cout << "lowest float:" << boost::numeric::bounds<float>::lowest();
cout << "lowest int:  " << boost::numeric::bounds<int>::lowest();

您可能还会发现boost::integer 库很有用。它为 C++ 带来了 C99 的一些整数支持(如int_least16_t),并可以帮助您选择最适合您特定需要的大小类型。一个例子:

boost::uint_t<20>::fast fastest20bits; // fastest unsigned integer that 
                                       // can hold at least 20 bits.
boost::int_max_value_t<100000>::least  // smallest integer that can store
                                       // the value 100000.

我经常发现,当我需要 boost::numeric/conversion 或 boost::integer 之一时,我都需要它们。

于 2009-04-29T09:30:04.487 回答
1

numeric_limits<int>::min返回最小的负数,所有浮点数类型,当我用 Sun CC & g++ 尝试时返回最小的正数。

我想这是因为“最小”和“最小”对浮点数意味着不同的东西。不过这有点奇怪。

Sun CC 和 g++ 都产生相同的结果:

短:最小:-32768 最大:32767

整数:最小值:-2147483648 最大值:2147483647

无符号整数:最小值:0 最大值:4294967295

长:最小:-2147483648 最大:2147483647

浮动:最小:1.17549e-38 最大:3.40282e+38

双倍:最小:2.22507e-308 最大:1.79769e+308

长双:最小:3.3621e-4932 最大:1.18973e+4932

无符号短:最小值:0 最大值:65535

无符号整数:最小值:0 最大值:4294967295

无符号长:最小值:0 最大值:429496729

template<typename T>
void showMinMax()
{
    cout << "min: " << numeric_limits<T>::min() << endl;
    cout << "max: " << numeric_limits<T>::max() << endl;
    cout << endl;
}

int main()
{
cout << "short:";
showMinMax<short>()
...etc...etc..
于 2009-04-29T15:05:53.010 回答
1

一种解决方法是

double val = -std::numeric_limits<double>::max();

当然,这并不能解释 numerics_limits::min() 的奇怪行为,这可能是因为整数有不同的最小/最大边界(min = -2^n,max = 2^n- 1)但不适用于双打。

于 2009-04-29T08:09:43.900 回答
1

可以争论空向量的最小值的定义。如果向量为空,则没有最小元素。

更喜欢使用std::min_element代替:

int main()
{
    std::vector<int> v;
    std::generate_n(std::back_inserter(v), 1000, std::rand);

    std::vector<int>::iterator it  = std::min_element(v.begin(), v.end());
    if (it == v.end())
    {
        std::cout << "There is no smallest element" << std::endl;
    }
    else
    {
        std::cout << "The smallest element is " << *it << std::endl;
    }
}
于 2009-04-29T09:11:03.643 回答