9

Python 2 には と の 2 つの整数データ型がintありlong、特に整数オーバーフローを回避するために、必要に応じてそれらの間で自動的に変換されます。

Python で C 関数をシミュレートしていますが、整数オーバーフローを再度有効にする標準的な方法があるかどうか疑問に思っています。ナンスについては、私は使用しました

overflow_point = maxint + 1
if value > overflow_point:
    value -= 2 * overflow_point

同じことを行うためのより標準的な方法はありますか?

4

5 に答える 5

11

基本的な考え方は正しいと思いますが、微調整が必​​要です。

  1. 関数は でオーバーフローしませんがsys.maxint+1、オーバーフローするはずです。
  2. sys.maxint1 回の操作で数回超える可能性があります。
  3. 以下の負の値-sys.maxint-1も考慮する必要があります。

これを念頭に置いて、私は次のことを思いつきました。

import sys

def int_overflow(val):
  if not -sys.maxint-1 <= val <= sys.maxint:
    val = (val + (sys.maxint + 1)) % (2 * (sys.maxint + 1)) - sys.maxint - 1
  return val
于 2011-10-14T17:32:23.253 に答える
8

この関数は、数値をハードウェア整数のように変換する必要があります。アプリケーションによっては、操作の各段階でこの機能を適用する必要がある場合があります。

def correct(value, bits, signed):
    base = 1 << bits
    value %= base
    return value - base if signed and value.bit_length() == bits else value

次のショートカット関数は、値を適切な範囲に「キャスト」するのに役立ちます。

byte, sbyte, word, sword, dword, sdword, qword, sqword = (
    lambda v: correct(v, 8, False), lambda v: correct(v, 8, True),
    lambda v: correct(v, 16, False), lambda v: correct(v, 16, True),
    lambda v: correct(v, 32, False), lambda v: correct(v, 32, True),
    lambda v: correct(v, 64, False), lambda v: correct(v, 64, True)
)

それらの使用方法の例として、Cで見られるバグを再現できます。バイトを使用してforループを記述し、0〜255を出力すると、ループが終了しない場合があります。次のプログラムは、この問題を示しています。

#! /usr/bin/env python3
def main():
    counter = 0
    while counter < 256:
        print(counter)
        counter = byte(counter + 1)


def correct(value, bits, signed):
    base = 1 << bits
    value %= base
    return value - base if signed and value.bit_length() == bits else value


byte, sbyte, word, sword, dword, sdword, qword, sqword = (
    lambda v: correct(v, 8, False), lambda v: correct(v, 8, True),
    lambda v: correct(v, 16, False), lambda v: correct(v, 16, True),
    lambda v: correct(v, 32, False), lambda v: correct(v, 32, True),
    lambda v: correct(v, 64, False), lambda v: correct(v, 64, True)
)


if __name__ == '__main__':
    main()
于 2013-01-09T20:37:22.047 に答える
5

あなたの関数は除算または右ビットシフトを使用していますか?そうでない場合は、2^32または2^64を法とする「正しい」答えが常に得られるため、計算の各段階でオーバーフローについて心配する必要はありません。結果を返す前(または除算や右ビットシフトを行う前)に、次のようなものを使用して標準の整数範囲に正規化することができます。

import sys

HALF_N = sys.maxint + 1
N = HALF_N * 2

def normalize(value):
    return (value + HALF_N) % N - HALF_N
于 2011-10-14T17:46:23.863 に答える
3

通常は問題とは見なされないため、これをネイティブで行う便利な方法があるかどうかはわかりません。そのため、python 開発者が組み込みたいものではありません。あなたのやり方は問題ないと思います。int組み込み型をサブクラス化し__add__()__sub__()、 などの演算子メソッドをオーバーライドして機能を含めることもできますが、それはやり過ぎかもしれません。

于 2011-10-14T17:18:13.613 に答える