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_MINDBL_MINまたはINT_MIN(またはそれぞれの値)を返します。したがって、あなたの質問は、なぜFLT_MINであり、とDBL_MINは異なる方法で定義されている必要がありますINT_MIN

残念ながら、後者の質問に対する答えはわかりません。

私の疑惑は、それが実際的な目的のためにそのように定義されたということです。整数の場合、通常、最小値と最大値が重要になるオーバーフロー/アンダーフローが問題になります。

浮動小数点数の場合、計算の結果、値がゼロより大きくなる可能性がありますが、その浮動小数点タイプの表現可能な最小の小数よりも小さいという点で、別の種類のアンダーフローが存在します。表現可能な最小の浮動小数点値を知っていると、問題を回避できます。非正規化数/非正規化数に関するウィキペディアの記事も参照してください。

于 2009-04-29T08:52:51.707 に答える
1

numeric_limits<int>::minSun CC&g ++で試したときに、すべての浮動小数点数タイプで最小の負の数を返し、最小正の数を返しました。

これは、「最小」と「最小」が浮動小数点数で異なることを意味するためだと思います。しかし、それは少し奇妙です。

SunCCとg++はどちらも同じ結果を生成します:

短い:最小:-32768最大:32767

int:min:-2147483648 max:2147483647

unsigned int:min:0 max:4294967295

ロング:最小:-2147483648最大:2147483647

フロート:最小:1.17549e-38最大:3.40282e + 38

ダブル:最小:2.22507e-308最大:1.79769e + 308

ロングダブル:最小:3.3621e-4932最大:1.18973e + 4932

unsigned short:min:0 max:65535

unsigned int:min:0 max:4294967295

unsigned long:min:0 max: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()の奇妙な動作を説明していません。これは、整数に対して異なる最小/最大境界があるという事実の結果である可能性があります(最小= -2^n、最大= 2^n- 1) ただし、ダブルスの場合は除きます。

于 2009-04-29T08:09:43.900 に答える
1

根拠はよくわかりませんが、予想される動作です。まあ、それが Josuttis (そしておそらく標準) がそれをどのように説明しているかという意味で!

min(): "有限値の最小値 (非正規化を伴う浮動小数点型の正規化された最小値)。"

型が整数 ( )ではなく、非正規化 ( )があるかどうかを知ることができる限り、その型で表現可能な最小値を返します。それ以外の場合は、最小が返されます。これは負の可能性があります。numeric_limits<>::is_integernumeric_limits<>::has_denormmin()

より一貫したインターフェイスについては、Boost 数値/変換ライブラリを確認してください。具体的にはbounds特性クラス。ここにスニペットがあります:

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

boost::integer ライブラリも便利です。これは、C99 の整数サポート ( などint_least16_t) の一部を C++ にもたらし、特定のニーズに最適なサイズの型を選択するのに役立ちます。例:

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

空ベクトルの最小値の定義については、議論することができます。ベクトルが空の場合、最小の要素はありません。

代わりに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 に答える