2012-01-23 7 views
5

मैं एक पहेली कर रहा हूं जहां मुझे आदेश 10^18 के साथ सौदा करना है। हालांकि, मुझे लगता है कि पाइथन सभी क्षेत्रों में बहुत बड़ी संख्या को संभालने में सक्षम नहीं है।क्यों पाइथन सभी क्षेत्रों में बहुत बड़ी संख्या का संचालन नहीं कर रहा है?

विशिष्ट होने के लिए, यदि हम एक = 1000000000000000000 (10^18) असाइन करते हैं और मूल अंकगणितीय गणना (+, -, /, *) करते हैं, तो इसका जवाब मिलता है। हालांकि, जब मैं इसे रेंज में उपयोग करता हूं()

>>> a = 1000000000000000000 
>>> a/2 
500000000000000000L 
>>> a*2 
2000000000000000000L 
>>> a+a 
2000000000000000000L 
>>> a*a 
1000000000000000000000000000000000000L 
>>> range(a) 

Traceback (most recent call last): 
    File "<pyshell#5>", line 1, in <module> 
    range(a) 
OverflowError: range() result has too many items 
>>> xrange(a) 

Traceback (most recent call last): 
    File "<pyshell#6>", line 1, in <module> 
    xrange(a) 
OverflowError: Python int too large to convert to C long 

मैंने पायथन 2.7 का उपयोग किया।

  1. मैं ऐसे मामलों को कैसे संभाल सकता हूं ?, ऐसी संख्याओं को रखने वाले पहेली से निपटने का सबसे अच्छा तरीका क्या है। (ए ट्यूटोरियल/पुस्तक संदर्भ की सराहना किया जाएगा)
  2. क्यों अजगर रेंज में इसे संभाल करने में सक्षम नहीं है()/xrange()

मैं अजगर 2.7 में यह करने के लिए inbuild फ़ंक्शन का उपयोग करना चाहते हैं। क्या यह संभव नहीं है?

+2

संभावित डुप्लिकेट http://stackoverflow.com/questions/1482480/xrange2100-overflowerror-long-int-too-large-to-convert-to-int –

+2

मुझे संदेह है कि आप अपनी पहेली को सही तरीके से हल करने जा रहे हैं । आज के कंप्यूटर पर पाइथन के साथ 10^18 की गिनती 10000 वर्षों के क्रम में कहीं ले जाएगी। –

+0

itertools.count() इसके लिए एक विकल्प प्रतीत होता है लेकिन गिनती बहुत लंबा समय ले रही है। क्या कोई अन्य कुशल विकल्प है (ऐसी परिस्थितियों पर विचार करना जहां हमें बड़े मूल्यों की गिनती करने की आवश्यकता है; पहेली को हल करना) – Surya

उत्तर

10

पायथन 2.x, range और xrange सी long के साथ काम करने के लिए सीमित हैं और आपके बड़े पूर्णांक इसके लिए बहुत बड़े हैं। यह सीमा range और xrange के लिए किए गए कार्यान्वयन विकल्पों के कारण है।

पायथन 3.x में सीमा हटा दी गई है और आप range() को बहुत बड़े पूर्णांक के साथ निष्पादित कर सकते हैं।

>>> range(2**128) 
range(0, 340282366920938463463374607431768211456) 

official list of changes for Python 3 इस में क्या कहना है:

range() अब, xrange() व्यवहार करने के लिए प्रयोग किया जाता है की तरह बर्ताव को छोड़कर यह मनमाने ढंग से आकार के मूल्यों के साथ काम करता है। उत्तरार्द्ध अब मौजूद नहीं है।


अजगर में 2.x range() समारोह एक सूची लौट आए। स्पष्ट रूप से बहुत बड़ी श्रेणियों के लिए सभी तत्वों के लिए स्मृति आवंटित करने की कोई उम्मीद नहीं है। xrange() फ़ंक्शन xrange ऑब्जेक्ट देता है। documentation इसे "एक अपारदर्शी अनुक्रम प्रकार के रूप में वर्णित करता है जो समान सूची के समान मानों को उत्पन्न करता है, वास्तव में उन्हें एक साथ सभी को संग्रहीत किए बिना"। प्रलेखन यह कहने के लिए चला जाता है:

xrange() सरल और तेज़ होना है। कार्यान्वयन इसे प्राप्त करने के लिए प्रतिबंध लगा सकते हैं। पायथन के सी कार्यान्वयन ने सभी तर्कों को देशी सी लम्बाई ("छोटा" पायथन पूर्णांक) पर प्रतिबंधित कर दिया है, और यह भी आवश्यक है कि मूल सी में लंबे तत्वों में फिट तत्वों की संख्या हो।

यह पायथन 2.x में सीमाएं बताता है।


मुझे पूरा यकीन नहीं है कि आप बहुत बड़ी सीमाओं के लिए नए पायथन 3 समर्थन के साथ उपयोगी रूप से क्या कर सकते हैं। उदाहरण के लिए, मैं आपको यह सलाह नहीं दूंगा कि आप इसे आजमाएं:

2**128 in range(2**128) 

यह लंबे समय तक चलता रहेगा।


आप टिप्पणी में संकेत देते हैं कि आप बड़ी संख्या में गिनने के लिए कोड लिख रहे हैं। आप इस इस तरह के कोड के साथ अजगर में तुच्छता से कर सकते हैं:

i = 0 
while i<N: 
    doSomething(i) 
    i += 1 

लेकिन आपको लगता है कि अगर N एक बड़ी संख्या है, तो यह एक बहुत ही लंबा समय लगेगा की खोज करेंगे। आपके प्रश्न के अनुसार ऑर्डर 2 के N के मूल्यों के लिए कोई भी नहीं हो रहा है।

+0

मुझे लगता है कि मुझे समाधान के लिए एक और तरीका मिलना चाहिए क्योंकि एन तक पहुंचना आम तौर पर असंभव है। – Surya

+0

यह सही है। आप 2^18 तक गिनने की उम्मीद नहीं कर सकते हैं। –

+2

माइनर: आधुनिक पायथन 3 में, '2 ** 128 रेंज (2 ** 128) 'तुरंत चलेंगे क्योंकि' __contains__' विशेष-आधारित है। – DSM

1

आपकी समस्या यह है कि Python 2.7 में श्रेणी() सीमा में प्रत्येक मान की एक स्पष्ट सूची बनाती है - आपके पास ऐसी सूची बनाने के लिए पर्याप्त संसाधन नहीं हैं।

पायथन 3 इस व्यवहार को सुधारता है - और केवल मांग पर मूल्यों की गणना करता है ... जैसे कि जनरेटर अभिव्यक्ति द्वारा।

पायथन 2 xrange() फ़ंक्शन आपकी मदद नहीं करेगा क्योंकि यह मानों को पंजीकृत करने के लिए बाध्य है ... जो कि पाइथन 2 के लिए समझौता था, किसी भी संख्या के लिए श्रेणी() के विशाल ओवरहेड से बचने के लिए छोटे से छोटे।

एक दृष्टिकोण अपने स्वयं के जनरेटर जो मनमाना पूर्णांक से अधिक iterates परिभाषित करने के लिए हो सकता है - जैसे कुछ:

def genrange(min,max,stride=1): 
    val=min 
    while val<max: 
     yield val 
     val+=stride 

मेरे संदेह, तथापि, कि यह शायद चीजों की बड़ी योजना में एक गलती है है - आप के रूप में 32 बिट पूर्णांक में प्रत्येक मान के माध्यम से पुन: सक्रिय करने के लिए पर्याप्त संसाधन संसाधनों की संभावना नहीं है - एक (32 बिट) रजिस्टर की तुलना में एक पूर्णांक सीमा के लिए अकेले रहने दें। मुझे संदेह है कि आपकी समस्या का समाधान करने का एक बेहतर तरीका है जो पहली जगह में किसी सीमा पर निर्भर नहीं है।

+0

यह रेंज() जैसे फ़ंक्शन के लिए एक तरीका हो सकता है (कुशल नहीं हो सकता है)। हालांकि, मैं इसे एक समारोह में डालने के बजाय()) का उपयोग कर सकता था। मुझे लगता है कि यह समय जटिलता को भी कम करेगा। (निश्चित नहीं) – Surya

संबंधित मुद्दे