2009-02-11 8 views
71

मुझे रूबी में सिस्टम पूर्ण पूर्णांक निर्धारित करने में सक्षम होना चाहिए। किसी को पता है कि कैसे, या यदि यह संभव है?रूबी अधिकतम पूर्णांक

उत्तर

42

रूबी स्वचालित रूप से पूर्णांक को एक पूर्ण पूर्णांक वर्ग में परिवर्तित करता है जब वे बहते हैं, इसलिए वहां (व्यावहारिक रूप से) कोई सीमा नहीं है कि वे कितने बड़े हो सकते हैं।

आप मशीन के आकार के लिए देख रहे हैं, यानी 64 या 32-बिट, मैं this trick at ruby-forum.com पाया:

machine_bytes = ['foo'].pack('p').size 
machine_bits = machine_bytes * 8 
machine_max_signed = 2**(machine_bits-1) - 1 
machine_max_unsigned = 2**machine_bits - 1 

आप देख रहे हैं (Fixnum ऑब्जेक्ट का आकार पूर्णांकों पर्याप्त करने के लिए छोटे के लिए एक मशीन शब्द में स्टोर करें), बाइट्स की संख्या प्राप्त करने के लिए आप 0.size पर कॉल कर सकते हैं। मुझे लगता है कि यह 32-बिट बिल्डों पर 4 होना चाहिए, लेकिन मैं अभी इसका परीक्षण नहीं कर सकता। इसके अलावा, सबसे बड़ा फिक्सनम 2**30 - 1 (या 2**62 - 1) है, क्योंकि एक बिट का उपयोग ऑब्जेक्ट संदर्भ के बजाय इसे पूर्णांक के रूप में चिह्नित करने के लिए किया जाता है।

+1

बहुत यकीन है कि आप 2 ** (machine_size * 8) -1 चाहते हैं; 2 ** 4-1 = 15 जो बहुत बड़ी नहीं है। – Cebjyre

+0

अरे, मुझे लगता है कि मैंने बिट्स के बजाए बाइट्स के बारे में बहुत कुछ सोचना शुरू कर दिया। –

+10

चेतावनी: कोड बेकार है। संपादन पढ़ें, कोड को अनदेखा करें। यह रूबी के लिए अधिकतम कुछ भी नहीं मिला है। यह कोड के लिए पाता है जो टैग पॉइंटर्स का उपयोग नहीं करता है। –

11

रूबी फिक्समम्स स्वचालित रूप से बिग्नम में परिवर्तित हो जाते हैं।

class Fixnum 
N_BYTES = [42].pack('i').size 
N_BITS = N_BYTES * 8 
MAX = 2 ** (N_BITS - 2) - 1 
MIN = -MAX - 1 
end 
p(Fixnum::MAX) 

बेशर्मी एक ruby-talk discussion से फट:

उच्चतम संभव Fixnum आप कुछ इस तरह कर सकता है पता करने के लिए। अधिक जानकारी के लिए वहां देखो।

+5

यदि आप करते हैं 'पुट (Fixnum :: मैक्स +1) इस .class' वापस नहीं करता है' Bignum' है जैसे कि यह की तरह यह होना चाहिए लगता है: यह कोड स्निपेट सच्चाई पता चलता है। यदि आप '8' से' 16' बदल देंगे तो यह होगा। –

+0

यह अब उपलब्ध नहीं है – allenhwkim

12

दोस्ताना मैनुअल पढ़ना? कौन ऐसा करना चाहता है?

start = Time.now 
largest_known_fixnum = 1 
smallest_known_bignum = nil 

until smallest_known_bignum == largest_known_fixnum + 1 
    if smallest_known_bignum.nil? 
    next_number_to_try = largest_known_fixnum * 1000 
    else 
    next_number_to_try = (smallest_known_bignum + largest_known_fixnum)/2 # Geometric mean would be more efficient, but more risky 
    end 

    if next_number_to_try <= largest_known_fixnum || 
     smallest_known_bignum && next_number_to_try >= smallest_known_bignum 
    raise "Can't happen case" 
    end 

    case next_number_to_try 
    when Bignum then smallest_known_bignum = next_number_to_try 
    when Fixnum then largest_known_fixnum = next_number_to_try 
    else raise "Can't happen case" 
    end 
end 

finish = Time.now 
puts "The largest fixnum is #{largest_known_fixnum}" 
puts "The smallest bignum is #{smallest_known_bignum}" 
puts "Calculation took #{finish - start} seconds" 
+0

यह एकमात्र ऐसा उत्तर लगता है जो फिक्सनम से बिग्नम में संक्रमण पर नंबर लौटाता है, जो मेरे लिए, इसका मतलब है कि रूबी में सबसे बड़ा फिक्सम है। –

78
FIXNUM_MAX = (2**(0.size * 8 -2) -1) 
FIXNUM_MIN = -(2**(0.size * 8 -2)) 
+5

आपने साइन के लिए 1 के बजाय 2 बिट्स क्यों घटाए? मैंने इसका परीक्षण किया और यह सही लगता है, लेकिन रूबी साइन के लिए 2 बिट्स का उपयोग क्यों करती है? – Matthias

+27

@ माथियास मान को एक पूर्णांक के रूप में चिह्नित करने के लिए एक अतिरिक्त बिट का उपयोग किया जाता है (जैसा किसी ऑब्जेक्ट के पॉइंटर के विपरीत होता है)। –

+0

दिलचस्प, धन्यवाद! – Matthias

0

के रूप में @ जोर्ग डब्ल्यू Mittag ने कहा: JRuby में, ठीक संख्या आकार हमेशा 8 बाइट्स लंबा है।

fmax = ->{ 
    if RUBY_PLATFORM == 'java' 
    2**63 - 1 
    else 
    2**(0.size * 8 - 2) - 1 
    end 
}.call 

p fmax.class  # Fixnum 

fmax = fmax + 1 

p fmax.class  #Bignum 
संबंधित मुद्दे