[ruby] 루비 최대 정수

Ruby에서 시스템 최대 정수를 결정할 수 있어야합니다. 방법을 아는 사람, 가능하다면?



답변

Ruby는 정수가 오버플로 될 때 자동으로 큰 정수 클래스로 변환하므로 크기에 제한이 없습니다.

머신의 크기 (예 : 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가되어야한다고 생각하지만 지금은 테스트 할 수 없습니다. 또한 객체 참조 대신 정수로 표시하는 데 1 비트가 사용되기 때문에 가장 큰 Fixnum은 분명히 2**30 - 1(또는 2**62 - 1)입니다.


답변

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


답변

친숙한 매뉴얼을 읽고 계십니까? 누가하고 싶어?

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"


답변

루비에서 Fixnums는 자동으로 Bignums로 변환됩니다.

가능한 가장 높은 Fixnum을 찾으려면 다음과 같이 할 수 있습니다.

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)

루비-토크 토론 에서 뻔뻔스럽게 찢어졌습니다 . 자세한 내용은 거기를 참조하십시오.


답변

Bignum과 Fixnum이 Integer로 통합 되었기 때문에 Ruby 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

오버플로가 발생하지 않고 메모리 부족이 발생합니다.


답변

@ Jörg W Mittag가 지적했듯이 jruby에서 수정 번호 크기는 항상 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


답변