Hello, I need to be able to determine a systems maximum integer in Ruby. Anybody know how, or if it's possible?
In ruby Fixnums are automatically converted to Bignums.
To find the highest possible Fixnum you could do something like this:
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)
Shamelessly ripped from a ruby-talk discussion. Look there for more details.
Ruby automatically converts integers to a large integer class when they overflow, so there's (practically) no limit to how big they can be.
If you are looking for the machine's size, i.e. 64- or 32-bit, I found this trick at ruby-forum.com (http://www.ruby-forum.com/topic/177435):
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
Edit: If you are looking for the size of Fixnum objects (integers small enough to store in a single machine word), you can call 0.size
to get the number of bytes. I would guess it should be 4 on 32-bit builds, but I can't test that right now. Also, the largest Fixnum is apparently 2**30 - 1
(or 2**62 - 1
), because one bit is used to mark it as an integer instead of an object reference.
Reading the friendly manual? Who'd want to do that?
start = Time.now
largest_known_fixnum = 1
smallest_known_bignum = nil
until (smallest_known_bignum and 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
raise "Can't happen case" if next_number_to_try <= largest_known_fixnum or (smallest_known_bignum and next_number_to_try >= smallest_known_bignum)
if next_number_to_try.class == Bignum
smallest_known_bignum = next_number_to_try
elsif next_number_to_try.class == Fixnum
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"
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))