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 - 1Edit: If you are looking for the size of Fixnum objects (integers small enough to store in a single machine word), you can call
0.sizeto 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 apparently2**30 - 1(or2**62 - 1), because one bit is used to mark it as an integer instead of an object reference.Cebjyre : Pretty sure you want 2**(machine_size * 8) -1; 2**4-1=15 which is not a very large anything.Matthew Crumley : Whoops, I guess I started thinking too much about bytes instead of bits. -
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))
0 comments:
Post a Comment