2009-02-11 34 views

Respuesta

42

Ruby convierte automáticamente enteros a una clase entera grande cuando se desbordan, por lo que no hay límite (prácticamente) para lo grandes que pueden ser.

Si usted está buscando para el tamaño de la máquina, es decir, de 64 o de 32 bits, encontré 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 

Si usted está buscando el tamaño de los objetos Fixnum (enteros suficiente para pequeños almacenar en una sola palabra de máquina), puede llamar al 0.size para obtener el número de bytes. Supongo que debería ser 4 en compilaciones de 32 bits, pero no puedo probar eso ahora. Además, el Fixnum más grande es aparentemente 2**30 - 1 (o 2**62 - 1), porque un bit se usa para marcarlo como un número entero en lugar de una referencia de objeto.

+1

Bastante seguro que quiere 2 ** (machine_size * 8) -1; 2 ** 4-1 = 15 que no es algo muy grande. – Cebjyre

+0

Vaya, creo que comencé a pensar demasiado sobre bytes en lugar de bits. –

+10

ADVERTENCIA: el código es inútil. Lea la edición, ignore el código. No encuentra el máximo de nada para Ruby. Lo encuentra para código que no usa punteros etiquetados. –

11

En ruby, los Fixnums se convierten automáticamente en Bignums.

Para encontrar la más alta Fixnum posible que usted podría hacer algo como esto:

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) 

Desvergonzadamente ser copiados desde un ruby-talk discussion. Mire allí para más detalles.

+5

Si lo hace 'puts (Fixnum :: MAX + 1) .class' este no devuelve' Bignum' como parece como debería. Si cambia '8' a' 16', lo hará. –

+0

esto no está disponible ahora – allenhwkim

12

¿Lees el manual de instrucciones? ¿Quién querría hacer eso?

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

Esta parece ser la única respuesta que devuelve números en la transición de Fixnum a Bignum, que, para mí, significa que es el Fixnum más grande en Ruby. –

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

¿Por qué restan 2 bits en lugar de 1 para el signo? Probé esto y parece ser correcto, pero ¿por qué Ruby usa 2 bits para el signo? – Matthias

+27

@Matthias Se usa un bit adicional para marcar el valor como un entero (a diferencia de un puntero a un objeto). –

+0

Interesante, gracias! – Matthias

0

como @ Jörg W Mittag señaló: en jruby, fijar el tamaño num es siempre de 8 bytes de longitud. Este fragmento de código muestra la verdad:

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 
Cuestiones relacionadas