web-dev-qa-db-ja.com

なぜ2⁶³のサイズは36バイトですが、2⁶³-1は24バイトしかないのですか?

Pythonのすべてがオブジェクトです。したがって、Pythonのintのサイズは通常より大きくなります。

_>>> sys.getsizeof(int())
24
_

わかりましたが、なぜ1つだけではなく_2⁶³_と比較しても_2⁶³ - 1_にさらに12バイト必要なのですか

_>>> sys.getsizeof(2**63)
36
>>> sys.getsizeof(2**62)
24
_

_2⁶³_はlongで、_2⁶³-1_はintですが、なぜ12バイトの違いがあるのでしょうか?

これ以上直感的ではない、私はいくつかの他のことを試しました:

_>>> a = 2**63
>>> a -= 2**62
>>> sys.getsizeof(a)
36
_

aは、現在intにある場合でも、longとして保存されます。それは驚くことではありません。しかし:

_>>> a -= (2**63 - 1)
>>> a = 2**63
>>> a -= (2**63 - 1)
>>> a
1L
>>> sys.getsizeof(a)
28
_

新しいサイズ。

_>>> a = 2**63
>>> a -= 2**63
>>> a
0L
>>> sys.getsizeof(a)
24
_

24バイトに戻りますが、まだ長いです。

最後に私が得たもの:

_>>> sys.getsizeof(long())
24
_

質問:

これらのシナリオでメモリストレージはどのように機能しますか?

サブ質問:

私たちの直感が私たちにわずか1ビットであると言うことを追加するために12バイトのギャップがあるのはなぜですか?

なぜint()long()は24バイトですが、long(1)は既に28バイトでint(2⁶²)ですか?

NB:Python 3.Xの動作は少し異なりますが、より直感的ではありません。ここでは、Python 2.7 ;以前のバージョンではテストしませんでした。

51
T.Nel

私はドキュメントでそれを見つけられませんでしたが、ここに私の説明があります。

Python 2は、値がintに格納できる値を超えると、intlongに暗黙的に昇格させます。新しい型のサイズ(long)はlongのデフォルトサイズであり、これは32です。今後、変数のサイズはその値によって決定されます。上下。

from sys import getsizeof as size
a = 1
n = 32

# going up
for i in range(10):
    if not i:
        print 'a = %100s%13s%4s' % (str(a), type(a), size(a))
    else:
        print 'a = %100s%14s%3s' % (str(a), type(a), size(a))
    a <<= n

# going down
for i in range(11):
    print 'a = %100s%14s%3s' % (str(a), type(a), size(a))
    a >>= n


a =                                                                                                    1 <type 'int'>  24
a =                                                                                           4294967296 <type 'long'> 32
a =                                                                                 18446744073709551616 <type 'long'> 36
a =                                                                        79228162514264337593543950336 <type 'long'> 40
a =                                                              340282366920938463463374607431768211456 <type 'long'> 44
a =                                                    1461501637330902918203684832716283019655932542976 <type 'long'> 48
a =                                           6277101735386680763835789423207666416102355444464034512896 <type 'long'> 52
a =                                 26959946667150639794667015087019630673637144422540572481103610249216 <type 'long'> 56
a =                       115792089237316195423570985008687907853269984665640564039457584007913129639936 <type 'long'> 60
a =              497323236409786642155382248146820840100456150797347717440463976893159497012533375533056 <type 'long'> 64
a =    2135987035920910082395021706169552114602704522356652769947041607822219725780640550022962086936576 <type 'long'> 68
a =              497323236409786642155382248146820840100456150797347717440463976893159497012533375533056 <type 'long'> 64
a =                       115792089237316195423570985008687907853269984665640564039457584007913129639936 <type 'long'> 60
a =                                 26959946667150639794667015087019630673637144422540572481103610249216 <type 'long'> 56
a =                                           6277101735386680763835789423207666416102355444464034512896 <type 'long'> 52
a =                                                    1461501637330902918203684832716283019655932542976 <type 'long'> 48
a =                                                              340282366920938463463374607431768211456 <type 'long'> 44
a =                                                                        79228162514264337593543950336 <type 'long'> 40
a =                                                                                 18446744073709551616 <type 'long'> 36
a =                                                                                           4294967296 <type 'long'> 32
a =                                                                                                    1 <type 'long'> 28

ご覧のとおり、型は最初にlongに対して大きすぎた後、intのままで、初期サイズは32でしたが、値によってサイズが変化します(より大きくすることも低くすることもできます[または等しい、明らかに] 32)

したがって、質問に答えるために、基本サイズはintの場合は24、longの場合は28です。また、longには大きな値を保存するためのスペースがあります(4から始まります)バイト-longの場合は32バイトですが、値に応じて上下できます)

あなたのサブ質問に関しては、新しい番号に一意のタイプ(一意のサイズ)を作成することは不可能であるため、Pythonにはlongタイプの「サブクラス」があり、したがって、古いlongの制限を超えた場合は、新しい番号を使用する必要があります。この番号ははるかに大きい番号を占めるため、数バイト多くなります。

5
CIsForCookies