フロートをその最大/最小値に初期化するにはどうすればよいですか?


100

フロートまたはダブルの絶対最大値または最小値をハードコードするにはどうすればよいですか?単純に反復して最大のものをキャッチすることで、配列の最大/最小を検索したいと思います。

フロートには正と負の無限大もありますが、代わりにそれらを使用する必要がありますか?もしそうなら、コードでそれをどのように表すのですか?

回答:


151

std::numeric_limitsで定義され<limits>ているwhich を使用して、型の最小値または最大値を見つけることができます(型に特化が存在する限り)。また、これを使用して無限大を取得することもできます(-負の無限大の場合は前にaを付けます)。

#include <limits>

//...

std::numeric_limits<float>::max();
std::numeric_limits<float>::min();
std::numeric_limits<float>::infinity();

コメントに記載されているように、min()可能な最小の正の値を返します。つまり、表現できる0に最も近い正の値。可能な最小値は、最大可能値のマイナスです。

もちろん、配列内の最大値または最小値を見つけるためのより良い選択である可能性のある、std::max_elementおよびmin_element関数(で定義<algorithm>)があります。


これを正確に使用するにはどうすればよいですか?何を含める必要がありますか?これまでに使ったことはないと思います。
Faken、2010

うーん...その最大要素関数は非常に便利だったでしょう...これは、正式ではなく自分でコーディングを学ぶときに起こります。ホイールを50回以上再発明することになります。これはceil()について最後に学んだときと同じです。ありがとうございました。
Faken、

18
@ヤコビー、numeric_limits <float> :: min()が最も負の値を意味するのではなく、正の最小値を意味することを明確にしたいかもしれません。
MSN

13
@killogre:C ++ 11が追加されましたnumeric_limits<T>::lowest()。これは、この問題を解決するために型で可能な最小(負)の値を返します。
Cornstalks 2013

3
std::numeric_limits<float>::min()表現できる最小の正の値を与えませ。最小の通常の単精度浮動小数点数を提供します。ゼロとこの数の間には非正規数もあります。特に、std::numeric_limits<float>::min()Givesです1.17549e-38が、表現可能な最小の非正規浮動小数点はnextafterf(0.0f, 1.0f) == 1.4013e-45fです。
nibot

45

最大の負の数には(または)を使用し、正の数には-FLT_MAX(または-DBL_MAX)を使用できます。これにより、可能なfloat(またはdouble)値の範囲が得られます。FLT_MAXDBL_MAX

おそらく使いたくないでしょうFLT_MIN。これは、フロートで表現できる最小の正の数値に対応し、フロートで表現できる最も負の値ではありません。

FLT_MINそして、FLT_MAX対応するstd::numeric_limits<float>::min()std::numeric_limits<float>::max()


私はこのバージョンを実際に使用すると思います。覚えるのが簡単で、より多くのシーンを作ってくれます。整数私は16進数を使用して初期化できます。でも、答えが私にいくつかの新しい非常に便利な機能を紹介したので、最良の答えはまだ残っています。
Faken、2010

2
「[ FLT_MIN]は、floatで表すことができる最小の正の絶対値に対応します」- これは当てはまりません通常の最小数です。非正規数もあります。
nibot

あなたは欲しいFLT_TRUE_MINに対応し、実際可能な限り最小のフロート、のためにstd::numeric_limits<float>::denorm_min()
クリス・ドッド

17

配列で最小/最大を見つけるために、最小/最大に初期化する必要はありません:

double largest = smallest = array[0];
for (int i=1; i<array_size; i++) {
    if (array[i] < smallest)
        smallest = array[i];
    if (array[i] > largest0
        largest= array[i];
}

または、複数回実行している場合:

#include <utility>

template <class iter>
std::pair<typename iter::value_type, typename iter::value_type> find_extrema(iter begin, iter end) {
    std::pair<typename iter::value_type, typename iter::value_type> ret;
    ret.first = ret.second = *begin;
    while (++begin != end) {
        if (*begin < ret.first)
           ret.first = *begin;
        if (*begin > ret.second)
           ret.second = *begin;
   }
   return ret;
}

サンプルコードを提供することの欠点-他の人がすでに同じアイデアを提案しているのを見ています。

標準にはmin_elementとmax_elementがありますが、これらを使用すると、データを2回スキャンする必要があり、配列がまったく大きい場合に問題になる可能性があることに注意してください。最近の標準ではstd::minmax_elementfind_extrema上記と同じように動作するを追加することでこれに対処しています(1つのパスでコレクションの最小要素と最大要素の両方を検索します)。

編集:符号なしの配列でゼロ以外の最小値を見つける問題に対処:符号なしの値が極端に達すると、「ラップアラウンド」することに注意してください。最小のゼロ以外の値を見つけるには、比較のためにそれぞれから1を減算します。ゼロの値はすべて、タイプの可能な最大値に「折り返し」ますが、他の値間の関係は保持されます。完了したら、見つけた値に1を加えます。

unsigned int min_nonzero(std::vector<unsigned int> const &values) { 
    if (vector.size() == 0)
        return 0;
    unsigned int temp = values[0]-1;
    for (int i=1; i<values.size(); i++)
        if (values[i]-1 < temp)
            temp = values[i]-1;
    return temp+1;
}

これはまだ初期値に最初の要素を使用していますが、「特別な場合」のコードは必要ありません。これは可能な限り最大の値に折り返されるため、ゼロ以外の値はより小さいと比較されます。結果は最小の非ゼロ値になります。ベクトルに非ゼロ値が含まれていない場合は、結果は0になります。


しかし、あなたは私から+1を受け取ります!
Dan Diplo、2010

1
最小のゼロ以外の値が必要な場合があるため(たとえば、符号なし整数の場合、データに多くの興味のないゼロが含まれる傾向があるため)、max minsに初期化します。最初の要素がゼロでないことを確認するために追加のチェックを実行するのではなく、それを初期化することは私には理にかなっているようです。
Faken、

@Faken:それでもあなたは扱いが可能な最大値としてゼロという比較関数を定義することができ、あなたはまだ使用できるようにstd::min_elementbool less_ignoring_zero(unsigned a, unsigned b) { if (a == 0) return false; if (b == 0) return true; return a < b; }
UncleBens

2
@Jerry:C ++ 0xはminmax_elementを追加して、あなたが言及した問題に対処します。(ただし、ゼロを無視することはできません...)
UncleBens 2010

1
初期化時に最初の要素が利用できない場合はどうなりますか?これはオンライン処理で
頻繁に

5

配列の最小値を手動で見つけるために、floatの最小値を知る必要はありません:

float myFloats[];
...
float minimum = myFloats[0];
for (int i = 0; i < myFloatsSize; ++i)
{
  if (myFloats[i] < minimum)
  {
    minimum = myFloats[i];
  }
}

そして、最大値のための同様のコード。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.