Devo essere in grado di determinare un numero intero massimo di sistemi in Ruby. Qualcuno sa come o se è possibile?
Risposte:
Ruby converte automaticamente gli interi in una grande classe di interi quando superano, quindi non c'è (praticamente) alcun limite a quanto possono essere grandi.
Se stai cercando la dimensione della macchina, cioè 64 o 32 bit, ho trovato questo trucco su 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
Se stai cercando la dimensione degli oggetti Fixnum (numeri interi abbastanza piccoli da poter essere memorizzati in una singola parola macchina), puoi chiamare 0.size
per ottenere il numero di byte. Immagino che dovrebbe essere 4 su build a 32 bit, ma non posso testarlo in questo momento. Inoltre, il Fixnum più grande è apparentemente 2**30 - 1
(o 2**62 - 1
), perché un bit viene utilizzato per contrassegnarlo come numero intero anziché come riferimento a un oggetto.
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))
Fixnum
è sempre a 64 bit (non 63 o 31 bit come in YARV) indipendentemente dalla dimensione della parola macchina e non è presente alcun bit di tag.
Leggere il manuale amichevole? Chi vorrebbe farlo?
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"
In ruby Fixnum vengono convertiti automaticamente in Bignum.
Per trovare il Fixnum più alto possibile potresti fare qualcosa del genere:
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)
Spudoratamente strappato da una discussione sui discorsi rubini . Guarda lì per maggiori dettagli.
puts (Fixnum::MAX + 1).class
non ritorna Bignum
come sembra che dovrebbe. Se si modifica 8
per 16
lo farà.
Non c'è un massimo da Ruby 2.4, poiché Bignum e Fixnum sono stati unificati in Integer. vedere la caratteristica # 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
Non ci sarà alcun trabocco, quello che succederebbe è un esaurimento della memoria.
come ha sottolineato @ Jörg W Mittag: in jruby, la dimensione del numero fisso è sempre lunga 8 byte. Questo frammento di codice mostra la verità:
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