long 値の割り当て

limits.h 標準ライブラリー・ヘッダー・ファイルで定義される long 型整数の限界は、次の表で示すように、32 ビット・モードと 64 ビット・モードでは異なります。

表 2. 32 ビット・モードおよび 64 ビット・モードにおける長整数の定数限界

シンボリック定数 モード 16 進数 10 進数
LONG_MIN (signed long の最小値) 32 ビット -(231) 0x80000000L -2,147,483,648
64 ビット -(263) 0x8000000000000000L -9,223,372,036,854,775,808
LONG_MAX (signed long の最大値) 32 ビット 231-1 0x7FFFFFFFL +2,147,483,647
64 ビット 263-1 0x7FFFFFFFFFFFFFFFL +9,223,372,036,854,775,807
ULONG_MAX (unsigned long の最大値) 32 ビット 232-1 0xFFFFFFFFUL +4,294,967,295
64 ビット 264-1 0xFFFFFFFFFFFFFFFFUL +18,446,744,073,709,551,615

この違いにより、次のような現象が生じます。

他の変数に割り当てたり、関数に渡されるときに long 型値がオーバーフローする場合は、以下を行う必要があります。

long 変数への定数値の割り当て

C および C++ では、定数の型識別は明示的規則に従って行われますが、多くのプログラムでは、16 進定数またはサフィックスのない定数を「型のない」変数として使用し、2 の補数表示によって 32 ビット・システムで許容される限界を超える値を表します。このような大きな値は 64 ビット・モードでは 64 ビット long 型に拡張されることが多いため、たいていの場合次のような境界領域で、予期しない結果が生じることがあります。

境界での予期しない副次作用の例をいくつか、次の表に示します。


表 3. long 型に割り当てられる定数の、境界での予期しない結果

long に割り当てられる定数 同等の値 32 ビット・モード 64 ビット・モード
-2,147,483,649 INT_MIN-1 +2,147,483,647 -2,147,483,649
+2,147,483,648 INT_MAX+1 -2,147,483,648 +2,147,483,648
+4,294,967,726 UINT_MAX+1 0 +4,294,967,296
0xFFFFFFFF UINT_MAX -1 +4,294,967,295
0x100000000 UINT_MAX+1 0 +4,294,967,296
0xFFFFFFFFFFFFFFFF ULONG_MAX -1 -1

サフィックスのない定数では、型があいまいになることがあります。その場合、sizeof 演算の結果を変数に割り当てる場合など、プログラムの他の部分に影響が出ることが考えられます。例えば、32 ビット・モードでは、コンパイラーが 4294967295 (UINT_MAX) のような数値を unsigned long として入力すると、sizeof は 4 バイトを戻します。64 ビット・モードでは、この同じ数値が signed long となり、sizeof は 8 バイトを戻します。定数を関数に直接渡すと、同様の問題が起こります。

このような問題を回避するには、サフィックス L (long 型定数の場合) または UL (unsigned long 型定数の場合) を使用して、プログラムの他の部分における割り当てや式の計算に影響を与えると思われる定数をすべて明示的に入力します。上記の例では、4294967295U のように数値にサフィックスを付けると、コンパイラーは、32 ビット・モードまたは 64 ビット・モードで、この定数を常に unsigned int と認識するようになります。

long 値のビット・シフト

long 値を左にビット・シフトした場合、 32 ビット・モードと 64 ビット・モードでは結果が異なります。下記の表の例は、以下のコード・セグメントを使用して long 型定数でビット・シフトを実行した場合の結果を示したものです。

long l=valueL<<1;

表 4. long 値のビット・シフトの結果

初期値 シンボリック定数 ビット・シフト後の値
32 ビット・モード 64 ビット・モード
0x7FFFFFFFL INT_MAX 0xFFFFFFFE 0x00000000FFFFFFFE
0x80000000L INT_MIN 0x00000000 0x0000000100000000
0xFFFFFFFFL UINT_MAX 0xFFFFFFFE 0x1FFFFFFFE

IBM Copyright 2003