मुझे रूबी में एक सिस्टम अधिकतम पूर्णांक निर्धारित करने में सक्षम होने की आवश्यकता है। किसी को पता है कि कैसे, या यदि यह संभव है?
जवाबों:
जब वे ओवरफ्लो होते हैं तो रूबी स्वतः पूर्णांकों को एक बड़े पूर्णांक वर्ग में बदल देती है, इसलिए (व्यावहारिक रूप से) उनकी कोई सीमा नहीं होती कि वे कितने बड़े हो सकते हैं।
यदि आप मशीन के आकार की तलाश में हैं, अर्थात 64- या 32-बिट, तो मुझे यह ट्रिक 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
) है, क्योंकि एक बिट का उपयोग ऑब्जेक्ट संदर्भ के बजाय पूर्णांक के रूप में चिह्नित करने के लिए किया जाता है।
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))
Fixnum
मशीन शब्द आकार की परवाह किए बिना , हमेशा 64 बिट (YARV में 63 या 31 बिट की तरह नहीं) होता है, और कोई टैग बिट नहीं होता है।
अनुकूल मैनुअल पढ़ना? कौन ऐसा करना चाहता है?
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"
रूबी में फिक्सनम स्वचालित रूप से Bignums में परिवर्तित हो जाते हैं।
उच्चतम संभव फिक्सनम को खोजने के लिए आप कुछ इस तरह से कर सकते हैं:
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)
शालीनता भरी चर्चा से बेशर्म हो गया । अधिक जानकारी के लिए वहाँ देखें।
puts (Fixnum::MAX + 1).class
यह वापस नहीं Bignum
आता है जैसा लगता है कि यह चाहिए आप को बदलते हैं 8
करने के लिए 16
कहीं भी होगी।
रूबी 2.4 के बाद से कोई अधिकतम नहीं है, क्योंकि बिग्नम और फिक्सनम इंटीजर में एकीकृत हो गए। फ़ीचर # 12005 देखें
> (2 << 1000).is_a? Fixnum
(irb):322: warning: constant ::Fixnum is deprecated
=> true
> 1.is_a? Bignum
(irb):314: warning: constant ::Bignum is deprecated
=> true
> (2 << 1000).class
=> Integer
कोई अतिप्रवाह नहीं होगा, जो होगा वह स्मृति से बाहर है।
जैसा कि @ Jörg W Mittag ने बताया: जूरी में, फिक्स संख्या का आकार हमेशा 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