NumPyの固定幅整数のオーバーフロー

NumPyの固定幅整数のオーバーフロー

説明

NumPyのint8、int16、int32、int64などの固定幅整数型は、範囲を超えると値が折り返すことがあります。検証せずに金額、サイズ、繰り返し回数の計算に使うと、意図しない値になる可能性があります。

想定される影響

  • サイズや回数が想定より小さく計算され、制限処理が正しく動かない可能性があります。
  • 負の値や折り返した値によって、決済、割り当て、数値処理が誤動作するおそれがあります。

対処方法

  • 計算前にnp.iinfo(dtype)で許容範囲を確認してください。
  • 正確さが必要な値はPythonのintや十分に大きな型で処理し、結果の範囲も検証してください。

例

非負整数の計算結果の範囲を確認する例です。外部入力から大きなべき乗を計算できる場合は、メモリと処理時間を制限するため、入力サイズと指数にも上限を設けてください。

変更前

python
result = np.power(number, pow_value, dtype=np.int64)

変更後

python
limit = np.iinfo(np.int64).max
base = int(number)
exponent = int(pow_value)
if base < 0 or exponent < 0:
    raise ValueError("unsupported input")

result = base ** exponent
if result > limit:
    raise ValueError("too large")

説明:

  • 変更前: int8、int16、int32、int64などの固定幅NumPy dtypeで計算すると、Pythonのintと異なり、範囲外の値が折り返すことがあります。
  • 変更後: Pythonのintで計算した後、固定幅dtypeの範囲内に収まることを確認し、折り返したNumPy整数が後続の計算に使われるのを防ぎます。

参考資料