python - 2⁶³ 36 बाइट्स का आकार क्यों है, लेकिन 2 1-1 केवल 24 बाइट्स है?




python-2.7 cpython (2)

2⁶³ के लिए 12 get बाइट्स क्यों मिलता है?

LP64 सिस्टम 1 पर , पायथन 2 int में ठीक तीन पॉइंटर-आकार के टुकड़े होते हैं:

  • पॉइंटर टाइप करें
  • संदर्भ गणना
  • वास्तविक मूल्य, एक C long int

वह कुल मिलाकर 24 बाइट्स है। दूसरी ओर, एक अजगर long होते हैं :

  • पॉइंटर टाइप करें
  • संदर्भ गणना
  • अंक गणना, एक सूचक आकार पूर्णांक
  • मूल्य अंकों के इनलाइन सरणी, प्रत्येक मूल्य के 30 बिट्स को पकड़े हुए, लेकिन 32-बिट इकाइयों में संग्रहीत (अप्रयुक्त बिट्स में कुशल ले जाने के लिए उपयोग किया जाता है / जोड़ और घटाव के दौरान उधार )

2 ** 63 को स्टोर करने के लिए 64 बिट्स की आवश्यकता होती है, इसलिए यह तीन 30-बिट अंकों में फिट बैठता है। चूंकि प्रत्येक अंक 4 बाइट्स चौड़ा होता है, पूरे पायथन long 24 + 3 * 4 = 36 बाइट्स लेंगे।

दूसरे शब्दों में, संख्या के आकार (8 अतिरिक्त बाइट्स) को अलग-अलग स्टोर करने के लिए long से अंतर आता है और इससे मूल्य को स्टोर करने के बारे में थोड़ा कम स्थान-कुशल होने के नाते (2 ** 63 के अंकों को संग्रहीत करने के लिए 12 बाइट्स)। आकार सहित, एक long 20 बाइट्स में मूल्य 2 ** 63। सरल int किसी भी मूल्य पर कब्जा कर लिया 8 बाइट्स की तुलना में मनाया 12-बाइट अंतर पैदा करता है।

यह ध्यान देने योग्य है कि पायथन 3 में केवल एक पूर्णांक प्रकार है, जिसे int कहा जाता है, जो चर-चौड़ाई है, और उसी तरह लागू किया गया है जैसे कि पायथन 2 long

1 64-बिट विंडोज में भिन्नता है कि यह 32-बिट long int बरकरार रखता है, संभवतः पुराने कोड के एक बड़े शरीर के साथ स्रोत संगतता के लिए जो 8, 16 और 32-बिट के लिए "सुविधाजनक" उपनाम के रूप में long "सुविधाजनक" उपनाम का उपयोग करता है। मान जो 16 और 32-बिट सिस्टम पर काम करने के लिए हुआ। __int64 विंडोज पर एक वास्तविक 64-बिट प्रकार प्राप्त करने के लिए, एक को __int64 या (नए संकलक संस्करणों पर) long long या int64_t उपयोग करना चाहिए। चूंकि पायथन 2 आंतरिक रूप से विभिन्न स्थानों में लंबे समय तक सी में फिटिंग पायथन पर निर्भर करता है, 64-बिट विंडोज पर भी sys.maxint 2**31-1 रहता है। यह क्विर्क पाइथन 3 में भी तय किया गया है, जिसकी अधिकतम अवधारणा नहीं है।

अजगर में सब कुछ एक वस्तु है। तो पायथन में एक इंट का आकार सामान्य से बड़ा होगा।

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

ठीक है, लेकिन 2 2⁶³ की तुलना में 2 2⁶³ लिए 12 और बाइट्स क्यों लेता है 2⁶³ - 1 और 2⁶³ - 1 ही नहीं?

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

मुझे लगता है कि 2 2⁶³ एक लंबी और 2⁶³-1 एक इंट है, लेकिन अंतर के 12 बाइट्स क्यों?

अधिक सहज नहीं है, मैंने कुछ अन्य चीजों की कोशिश की:

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

a अभी भी एक लंबे समय के रूप में संग्रहीत किया जाता है, भले ही यह एक int में हो सकता है। तो यह आश्चर्य की बात नहीं है। परंतु:

>>> 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

सवाल:

उन स्थितियों में मेमोरी स्टोरेज कैसे काम करता है?

उप-प्रश्न:

हमारे अंतर्ज्ञान को जो कुछ बताता है उसे जोड़ने के लिए 12 बाइट्स का अंतर क्यों है?

int() और long() 24 बाइट्स क्यों हैं, लेकिन long(1) पहले से ही 28 बाइट्स और int(2⁶²) ?

नायब: पायथन 3. एक्स थोड़ा अलग तरीके से काम कर रहा है, लेकिन अधिक सहज रूप से नहीं। यहां मैंने पायथन 2.7 पर ध्यान केंद्रित किया; मैंने पहले संस्करणों पर परीक्षण नहीं किया था।


जब मैंने इसे प्रलेखन में नहीं पाया, तो यहाँ मेरा स्पष्टीकरण है।

पायथन 2 int को long स्पष्ट रूप से बढ़ावा देता है, जब मूल्य उस मूल्य से अधिक हो जाता है जिसे इंट में संग्रहीत किया जा सकता है। नए प्रकार ( 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 तक)

तो, आपके प्रश्न का उत्तर देने के लिए, आधार का आकार 24 के लिए है, और long लिए 28, जबकि long लिए बड़े मूल्यों को बचाने के लिए भी जगह है (जो 4 बाइट्स के रूप में शुरू होता है - इसलिए long 32 बाइट्स long , लेकिन तदनुसार ऊपर और नीचे जा सकते हैं मूल्य के लिए)

आपके उप-प्रश्न के लिए, एक नए नंबर के लिए एक अद्वितीय प्रकार (एक अद्वितीय आकार के साथ) बनाना असंभव है, इसलिए पायथन में long प्रकार के "उप वर्ग" होते हैं, जो कई प्रकार की संख्या के साथ सौदा करते हैं, इसलिए, एक बार सीमा से अधिक होने पर अपने पुराने long आपको नए का उपयोग करना चाहिए, जो बहुत बड़ी संख्या के लिए भी खाता है, इसलिए, इसमें कुछ बाइट्स अधिक हैं।






python-internals