11

/usr/include/limits.h で次の定義を見つけました。

# define INT_MIN (-INT_MAX - 1)

# define INT_MAX 2147483647

また、このヘッダー ファイル内のすべての XXX_MAX は、数値定数から明示的に定義されているようです。

INT_MAX を定義する移植可能な方法 (プラットフォーム間で異なるワード サイズに対して) があるのだろうか?

私は次のことを試しました:

~((int)-1)

しかし、これは正しくないようです。

短い解説も好評です。

4

5 に答える 5

10

INT_MAX標準ヘッダーのについては、プリプロセッサディレクティブlimits.hで使用できるようにする必要があるという事実によって、実装者の手を縛られています。#ifこれにより、関連するものsizeofやキャストが除外されます。

実際の C 式で動作するバージョンが必要な場合は、おそらくこれで動作します。

(int)-1U/2 == (int)(-1U/2) ? (int)-1U : (int)(-1U/2)

ここでの概念はint、 と同じ数の値ビットunsigned、または 1 つ少ない値ビットを持つことができるということです。C 標準ではどちらも許可されています。それがどれであるかをテストするために、変換の結果を確認してください(int)-1U-1Uに適合する場合int、その値はキャストによって変更されない必要があるため、等式は true になります。-1Uが に適合しない場合int、キャストはタイプ の実装定義の結果になりintます。ただし、値が何であれ、可能な値の範囲だけで等値は偽になります。

技術的には、への変換intにより、実装定義の値が取得されるのではなく、実装定義のシグナルが発生する可能性があることに注意してください。コンパイル時。

于 2013-07-23T05:16:59.287 に答える
0

1 または 2 の補数表記、8 ビット/バイト、パディングなしを想定すると、次のようになります。

#define INT_MAX  ((1 << (sizeof(int)*8 - 2)) - 1 + (1 << (sizeof(int)*8 - 2)))

シフトや加算にオーバーフローは見られません。UBも見えません。CHAR_BIT8の代わりに使用できると思います。

1 と 2 の補数では、最大 int は になりますpower(2,(sizeof(int)*Bits_per_byte - 1) - 1。パワーの代わりにシフトを使用しますが、一度にシフトしすぎることはできません。なのでpower(2,(sizeof(int)*Bits_per_byte - 1)、半分を2回やって形成します。ただし、オーバーフローは禁物なので、最後ではなく、後半を追加する前に 1 を減算します。()評価順序を強調するために多くのを使用しました。

@caf で指摘されているように、このメソッドはパディング ビットがあると失敗します - 珍しいが可能です。

INT_MIN の計算は、21 の補数で機能させるのが少し難しいですが、同様のアプローチが機能しますが、それは別の問題です。

于 2013-07-23T03:54:06.873 に答える
0

まあ、試すことができます

#define INT_MAX (int) ((unsigned) -1 / 2)

これは、ワード サイズが異なり、符号付き整数値の表現が異なっていても、プラットフォーム間で機能する「はず」です。(unsigned) -1これはUINT_MAX、すべてビット 1 のパターンです。それを 2 で除算すると、対応する符号付き整数型の期待される最大値になり、符号を表すためにビットが費やされます。

しかし、なぜ?標準ヘッダー ファイルとその中で作成された定義は、移植可能であると想定されていません。

ところで、上で引用したあなたの定義はINT_MIN移植性がありません。これは、符号付き整数の 2 の補数表現に固有のものです。

于 2013-07-23T03:14:22.213 に答える