रूबी अधिकतम पूर्णांक


87

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

जवाबों:


49

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

यदि आप मशीन के आकार की तलाश में हैं, अर्थात 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) है, क्योंकि एक बिट का उपयोग ऑब्जेक्ट संदर्भ के बजाय पूर्णांक के रूप में चिह्नित करने के लिए किया जाता है।


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

वूप्स, मुझे लगता है मैं बिट्स के बजाय बाइट्स के बारे में बहुत ज्यादा सोचने लगा।
मैथ्यू क्रुमले

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

अब (2018-01-21) यह खिड़कियों पर 64 बिट रूबी में भी 32 बिट्स है (साइबर्विन के पास दूसरी तरफ उचित 64 बिट है)
ग्रेवॉल्फ

81
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))

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

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

2
यह कम से कम JRuby के लिए सही नहीं है। JRuby में, Fixnumमशीन शब्द आकार की परवाह किए बिना , हमेशा 64 बिट (YARV में 63 या 31 बिट की तरह नहीं) होता है, और कोई टैग बिट नहीं होता है।
जोर्ग डब्ल्यू मित्तग

13

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

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"

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

11

रूबी में फिक्सनम स्वचालित रूप से 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)

शालीनता भरी चर्चा से बेशर्म हो गया । अधिक जानकारी के लिए वहाँ देखें।


5
यदि आप ऐसा करते हैं तो puts (Fixnum::MAX + 1).classयह वापस नहीं Bignumआता है जैसा लगता है कि यह चाहिए आप को बदलते हैं 8करने के लिए 16कहीं भी होगी।
टिन मैन

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

1

रूबी 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

कोई अतिप्रवाह नहीं होगा, जो होगा वह स्मृति से बाहर है।


0

जैसा कि @ 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.