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))
Fixnum
머신 워드 크기에 관계없이 항상 64 비트 (YARV에서와 같이 63 비트 또는 31 비트가 아님)이며 태그 비트가 없습니다.
친숙한 매뉴얼을 읽고 계십니까? 누가하고 싶어?
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)
루비-토크 토론 에서 뻔뻔스럽게 찢어졌습니다 . 자세한 내용은 거기를 참조하십시오.
puts (Fixnum::MAX + 1).class
이것을 하면 Bignum
그것이해야 할 것처럼 보이는 것처럼 반환되지 않습니다 . 당신이 변경하는 경우 8
에 16
이를 것입니다.
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
오버플로가 발생하지 않고 메모리 부족이 발생합니다.