2012-02-22 13 views
4

ビット演算子のみを使用してINT_MAXの値を取得するにはどうすればよいですか?私はが1111111111(補数は1、従って小数は-1)であり、~0 >> 10111111111であると予想しました。これは最大ですが、まだ-1です。ビット操作でINT_MAXを取得

なぜビット演算を使用してINT_MAXの値を取得できますか?

答えて

9

~0UL >> 1を試してみてください:あなたが好きな何かを行うことができます。問題は、署名付きの型を扱う場合、Cが符号拡張された右シフトを実行することです。これは、あなたがまだ負の値を取っている理由です。なぜなら、そこにあった1ビットに合わせて別の1ビットがシフトしているからです。 (そのように-8 >> 1は、2つのことで、高速の部門のために好きな-4なります。)

+5

'〜0UL >> 1'はLONG​​_MAXです。 '〜0U >> 1'が必要です。たぶんそれを 'int'にキャストするかもしれないので、正しい型を持つでしょう。 – ugoren

+0

微妙だが良い点 - コンパイラの違いは、常に私の最高を得る。問題は、このANSIのいずれか、または実際の標準がないことですか? – Kaganar

+0

私は、標準がINT_MAXを使うと言っていると思います。あなたのソリューションは2の補数、つまり実際のCPUで動作します。代わりに、私は 'for(x = 0; x + 1> x; x ++);と思っています。 – ugoren

2

負の数を右にシフトすると、数値の新しいビットは1(負のままにする)になります。あなたは-1を得る理由。

編集:

int i=1; 
while (i<<1) i<<=1; 
i=~i; 
+0

は "であってもよいですか"?のように、すべての実装ではありませんか? –

+1

私は標準はそれが実装に依存していると言います。 – asaelr

+0

@PaulManta右シフトの負の数は実際に実装定義されています(6.5.7(5))。 'E1^2^E2'がその型で表現できない場合、' E1 << E2'は未定義の振る舞いであるため、あなたの代わりにこれの具体的な解釈に依存します未定義の動作。 –

2

あなたは符号なし整数として0を扱う場合は、コンパイラが署名したシフトを実行しません。

int i = ~0U >> 1; 

をこれにより、INT_MAX

1

(1 < < 31)-1)だけでなく

私の長年の質問を参照してください。これは古いスレッドですが、私はそれをグーグルで見つけようとしています。しかし、それは完全にビット単位ではなく、マシン上の "int"が32ビットであると仮定しています。

0
#include <stdio.h> 

int main(){ 
    int max = ~0U >> 1; 
    int min = ~max; 

    printf("Max = 0x%X, min = 0x%X", max, min); 
    return 0; 
} 

出力:

Max = 0x7FFFFFFF, min = 0x80000000 
関連する問題