2012-08-17 15 views
8

जब मैंने आईआरबी में 3 ** 557 की गणना करने की कोशिश की तो मुझे इस समस्या से मुलाकात हुई। रूबी और मैकरुबी दोनों मेरे मैक (ओएस एक्स 10.8) में स्थापित हैं। और रूबी का संस्करण 1.8.7 है, मैक्रूबी 0.12 (रूबी 1.9.2)। रिब और मैकिरब ने मुझे 3 ** 557 की गणना पर दो अलग-अलग उत्तर दिए। (मैकिरब सही है।)रुबी में एक्सपोनेंटिएशन 1.8.7 गलत जवाब देता है

$ irb 
>> 3**557 
=> 54755702179342762063551440788945541007926808765326951193810107165429610423703291760740244724326099993131913104272587572918520442872536889724676586931200965615875242243330408150984753872526006744122187638040962508934109837755428764447134683114539218909666971979603 

$ macirb 
irb(main):001:0> 3**557 
=> 57087217942658063217290581978966727348872586279944803346410228520919738045995056049600505293676159316424182057188730248707922985741467061108015301244570536546607487919981026877250949414156613856336341922395385463291076789878575326

और फिर मैंने कुछ बड़ा करने की कोशिश की, उदा। 3 ** 5337, और मुझे इस बार एक ही जवाब मिला।

तो, क्या यह रूबी 1.8.7 में एक बग है, या मुझे एक्सपोनिएशन की गणना करने के लिए एक और तरीका उपयोग करना चाहिए?

+0

रूबी से संबंधित नहीं विशेष रूप से, लेकिन आप को देखने के लिए चाहते हो सकता है [मॉड्यूलर घातांक] (http://en.wikipedia.org/wiki/Modular_exponentiation) परिणाम के साथ आप क्या कर रहे हैं इसके आधार पर। – jli

+0

मेरे पास एक एमआरआई प्री-1.9.3 स्थापित नहीं है, लेकिन यह सही परिणाम देता है। –

+0

मैक का कौन सा सटीक मॉडल आप उपयोग कर रहे हैं? मैं रूबी (1.8.7 पी 358) के उसी संस्करण के साथ अपने मैकप्रो (ज़ीऑन) पर इसे पुन: पेश नहीं कर सकता। न ही मैं 32 बिट्स में चल रहे पुराने 1.8.6 पर जा सकता हूं। –

उत्तर

3

गणना करते समय, रु फिक्सनम से बिग्नम में कनवर्ट करना चाहिए जब संख्या फिक्सनम की सीमा से परे हो। रूबी के पुराने संस्करणों के लिए, यह ** ऑपरेटर के साथ विफल रहता है:

$ ruby --version 
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0] 
$ irb 
>> 2 ** 62 
=> 4611686018427387904 
>> 2 ** 63 
=> -9223372036854775808 
>> 2 ** 64 
=> 0 

यह कहाँ विफल रहता है वास्तुकला का शब्द आकार पर निर्भर करता है। इस उदाहरण में iMac पर 64-बिट शब्द। आंतरिक रूप से, फिक्सम को एक लंबे पूर्णांक में डाला जाता है, और ऑपरेटर को लंबे समय तक संभाला जाता है। देशांतर शब्द आकार में अतिप्रवाह, और रूबी ungracefully लौटने 0.

ध्यान दें कि * ऑपरेटर ठीक से काम करता द्वारा इस से निपटने है (bignum में कनवर्ट करने), जहां ** विफल रहता है:

>> a = 2 ** 62 
=> 4611686018427387904 
>> 2 ** 63 
=> -9223372036854775808 
>> a * 2 
=> 9223372036854775808 
>> 2 ** 64 
=> 0 
>> a * 4 
=> 18446744073709551616 

एक करने के लिए ले जा रहा है रूबी का नया संस्करण इसे ठीक करेगा। यदि आप किसी नए संस्करण में नहीं जा सकते हैं, तो बड़ी शक्तियों के साथ फिक्सनम और ** का उपयोग करने से बचें।'10' किसी भी सत्ता में

def xpnt(base, exponent) 
    sum = base 
    while exponent >= 2 
     sum = sum * base 
     exponent -= 1 
    end 
    puts sum 
end 

एक भी '1' के साथ शुरू करना चाहिए और कुछ भी नहीं के बाद किया:

2

1.9.3 का उपयोग सही परिणाम उत्पन्न करता है। जब तक आपके पास वास्तव में कोई अच्छा कारण न हो, तब तक 1.9.3 या बेहतर उपयोग करने का प्रयास करें क्योंकि 1.8.7 चरणबद्ध हो रहा है।

यह भी ध्यान देने योग्य है कि लिनक्स पर 1.8.7-पी 358 के साथ परीक्षण करने के बाद मुझे सही उत्तर भी मिलता है। यह 1.8.7 के विशेष संस्करण में एक बग हो सकता है जिसका आप उपयोग कर रहे हैं।

+0

का उत्तर देते हैं धन्यवाद! यह एक्सकोड $ ruby ​​--version रूबी 1.8.7 (2012-02-08) के साथ स्थापित किया जा सकता है पैचलेवल 358) [सार्वभौमिक-डार्विन 12.0] – Vej

+0

एक्सकोड में रुबी शामिल नहीं है, लेकिन ओएस एक्स में आमतौर पर सिस्टम के साथ कुछ संस्करण शामिल होते हैं, हालांकि रूबी के बारे में गंभीर कोई भी 'आरवीएम' या 'आरबीएनवी' का उपयोग करता है ताकि इसे और अधिक के लिए स्विच किया जा सके। मौजूदा एक। आमतौर पर सिस्टम रूबी के साथ गड़बड़ करना अच्छा नहीं है क्योंकि यह तकनीकी रूप से सिस्टम के स्वामित्व में है और ऐप्पल द्वारा पैच किया जा सकता है। – tadman

+0

अब मैं अपने रूबी को 1.9.3-पी 1 9 4 में अपडेट करने के लिए आभूषण बॉक्स का उपयोग कर रहा हूं । – Vej

1

यह निश्चित रूप से एक बग है। यह शायद प्रोसेसर और/या संकलन विकल्पों पर निर्भर है।

मुझे आश्चर्य नहीं होगा अगर यह this commit द्वारा तय किया गया था।

जैसा कि अन्य ने कहा है, केवल सुरक्षा सुधार इसे आज 1.8.7 पर बनाते हैं, इसलिए 1.9.3 में अपग्रेड करें।

0

यह स्पष्ट रूप से एक्सपोनिएशन से संबंधित नहीं है। मुझे लगता है कि यह प्रतिनिधित्व के लिए आवश्यक 63 से 64 बिट्स के संक्रमण से संबंधित किसी भी तरह से है, हालांकि यह 100% संगत प्रतीत नहीं होता है।

>> 19**14 
=> 799006685782884121 
>> 19**15 
=> -3265617043834753317 
>> (19**14)*19 
=> -3265617043834753317 

और

>> 2**64-1 
=> -1 
>> 2**64 
=> 0 
>> 0x7fffffffffffffff 
=> 9223372036854775807 
अभी तक

>> 0x8000000000000000 
=> 9223372036854775808 

इसके अलावा: चल रहा है 32-बिट मोड में आईआरबी (arch -i386 irb), मैं इस बिंदु पर यह नहीं दिख रहा है, लेकिन इससे पहले:

>> 19**15 
=> 15181127029874798299 
>> 2**31 
=> -2147483648 
0

अपनी खुद की घातांक विधि लेखन एक और तरीका है करने के लिए यह जरूरी है कि त्रुटियों का उत्पादन नहीं करता प्रतीत हो रहा है लेकिन शून्य। रूबी के ** समारोह:

10 ** 40 
=> 10000000000000000000092233720368547758080 

कस्टम xpnt विधि:

xpnt 10, 40 
10000000000000000000000000000000000000000 
=> nil 
संबंधित मुद्दे