整数の定数や変数に保持できない数値を代入しようとした場合、Swift は不正な値で生成するのではなく、デフォルトでエラーを報告します。この振る舞いにより、大きすぎる、または小さすぎる数値を扱う際により安全になります。
例えば、整数型 Int16
は -32768
から 32767
までの符号付き整数値を保持することができます。この範囲外の数値を Int16
の定数または変数に設定しようとすると、エラーを引き起こします。
var potentialOverflow = Int16.max
// potentialOverflow は 32767 で、Int16 が保持できる最大値
potentialOverflow += 1
// エラーを引き起こす
値が大きくなりすぎるか、小さくなりすぎるときにエラー処理することで、境界値条件のコーディングがより柔軟になります。
しかし、オーバーフロー条件で利用できるビット数を切りたいときには、エラーを引き起こすのではなく、この振る舞いを選択することができます。Swift には、整数の計算にオーバーフローの振る舞いをする 3 つの算術オーバーフロー演算子があります。これらの演算子は、すべてアンパサンド (&
) で始まります。
- オーバーフロー加算 (
&+
) - オーバーフロー減算 (
&-
) - オーバーフロー乗算 (
&*
)
値のオーバーフロー
数値は正負どちらの方向にでもオーバーフローしえます。
次は、符号無し整数がオーバーフロー加算演算子 (&+
) で正の方向にオーバーフローする例です。
var unsignedOverflow = UInt8.max
// unsignedOverflow は 255 で、UInt8 が保持できる最大値
unsignedOverflow = unsignedOverflow &+ 1
// unsignedOverflow は 0
変数 unsignedOverflow
は、UInt8
が保持できる最大値(255
、2 進数で 11111111
)で初期化されています。そして、オーバーフロー加算演算子 (&+
) で 1
加算しています。UInt8
が保持できるサイズをちょうどオーバーし、下の図で示されているように範囲を越えてオーバーフローします。オーバーフロー加算した後、UInt8
の範囲内に残っている値は 00000000
で、ゼロになります。
符号無し整数が負の方向にオーバーフローするときにも同じようなことになります。次は、オーバーフロー減算演算子 (&-
) での例です。
var unsignedOverflow = UInt8.min
// unsignedOverflow は 0 で、UInt8 が保持できる最小値
unsignedOverflow = unsignedOverflow &- 1
// unsignedOverflow は 255
UInt8
が保持できる最小値はゼロで、2 進数で 00000000
です。オーバーフロー減算演算子 (&-
) で 00000000
から 1
を引くと、数値はオーバーフローして 11111111
、10 進数で 255
になります。
また、オーバーフローは符号付き整数でも起こります。符号付き整数に対する加算と減算は、Bitwise Left and Right Shift Operators で説明されているように、加算・減算される数値の一部に含まれる符号ビット付きでビット演算が実行されます。
var signedOverflow = Int8.min
// signedOverflow は -128 で、Int8 が保持できる最小値
signedOverflow = signedOverflow &- 1
// signedOverflow は 127
Int8
が保持できる最小値は -128
で、2 進数で 10000000
です。オーバーフロー演算子でこの 2 進数値から 1
を引くと、2 進数値の 01111111
になり、符号ビットが切り替わって Int8
が保持できる正の最大値 127
になります。
符号付きと符号無しの整数は共に、正の方向にオーバーフローした場合は最大の整数値から最小値に、負の方向にオーバーフローした場合は最小値から最大値になります。
Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.