12

これは非常に簡単な質問です(私が思うに)、変数タイプ (整数など)の制限を提供するSTLライブラリメソッドはあり ますか?これらの制限はコンピューターによって異なることは知っていますが、メソッドを介してそれらを取得する方法が必要ですよね?

また、変数型の制限を計算するメソッドを書くのは本当に難しいでしょうか?

私はただ興味があります!:)

ありがとう ;)。

4

4 に答える 4

38

使用std::numeric_limits:

// numeric_limits example
// from the page I linked
#include <iostream>
#include <limits>
using namespace std;

int main () {
  cout << boolalpha;
  cout << "Minimum value for int: " << numeric_limits<int>::min() << endl;
  cout << "Maximum value for int: " << numeric_limits<int>::max() << endl;
  cout << "int is signed: " << numeric_limits<int>::is_signed << endl;
  cout << "Non-sign bits in int: " << numeric_limits<int>::digits << endl;
  cout << "int has infinity: " << numeric_limits<int>::has_infinity << endl;
  return 0;
}
于 2009-12-27T20:08:20.487 に答える
12

「正しい」答えはすでに与えられていることがわかります<limits>。魔法を使って起こさせてください。質問は次のとおりであるため、たまたまその答えは満足のいくものではありません。

変数型の制限を計算するメソッドを書くのは本当に難しいでしょうか?

答えは、整数型は簡単、浮動小数点型は難しいです。これを行うために必要なアルゴリズムには、3 つの基本的なタイプがあります。符号付き、符号なし、および浮動小数点。最小値と最大値を取得する方法にはそれぞれ異なるアルゴリズムがあり、実際のコードにはビットの調整が含まれます。浮動小数点の場合、浮動小数点数と同じサイズの既知の整数型がない限り、ループする必要があります。タイプ。

それで、ここにあります。

署名なしは簡単です。最小値はすべてのビットが 0 の場合、最大値はすべてのビットが 1 の場合です。

const unsigned type unsigned_type_min = (unsigned type)0;    
const unsigned type unsigned_type_max = ~(unsigned type)0;

符号付きの場合、最小値は符号ビットが設定されているが他のすべてのビットがゼロの場合であり、最大値は符号ビットを除くすべてのビットが設定されている場合です。型のサイズがわからないと、符号ビットがどこにあるのかわかりませんが、いくつかのビットトリックを使用してこれを機能させることができます。

const signed type signed_type_max = (signed type)(unsigned_type_max >> 1);
const signed type signed_type_min = (signed type)(~(signed_type_max));

浮動小数点の場合、4 つの制限があります。正の制限のみを知っていれば十分ですが、負の制限は正の制限の符号を反転したものです。浮動小数点数を表現する方法は潜在的に多数ありますが、2 進数 (基数 10 ではなく) 浮動小数点数を使用する方法については、ほぼすべての人が IEEE 表現を使用します。

IEEE 浮動小数点の場合、最小の正の浮動小数点値は、指数の下位ビットが 1 で、他のすべてのビットが 0 の場合です。最大の負の浮動小数点値は、これのビット単位の逆数です。ただし、指定された浮動小数点型と同じサイズであることがわかっている整数型がなければ、ループを実行する以外にこのビット操作を行う方法はありません。浮動小数点型と同じサイズであることがわかっている整数型がある場合は、これを 1 回の操作で実行できます。

const float_type get_float_type_smallest() {
   const float_type float_1 = (float_type)1.0;
   const float_type float_2 = (float_type)0.5;
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ((byte*)&float_1)[ii] ^ ((byte*)&float_2)[ii];
   return u.fl;
   }

const float_type get_float_type_largest() {
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   u.fl = get_float_type_smallest();
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ~u.ab[ii];
   return -u.fl; // Need to re-invert the sign bit.
   }
于 2009-12-27T22:25:15.937 に答える
4

(C関連ですが、これはC++にも当てはまると思います)

また、コンパイラ用に limits.h を再作成できるスクリプトである" inquire "を試すこともできます。プロジェクトのホームページからの引用:

これは、最小および最大の [un]signed char/int/long、float/ [long] double の多くのプロパティなど、C コンパイラとそれが実行されるマシンの多くのプロパティを決定するプログラムです。

オプションとして、ANSI C float.h および limits.h ファイルを生成します。

さらにオプションとして、コンパイラがヘッダー ファイルを正しく読み取るかどうかもチェックします。

これは、浮動小数点数の最小値や最大値など、多くの制限値を使用してコンパイラを実行するため、コンパイラのテスト ケースとして適しています。

于 2009-12-27T20:13:54.483 に答える
2
#include <limits>

std::numeric_limits<type>::max() // min() etc
于 2009-12-27T20:15:33.060 に答える