module MessagePack::Bigint

Constants

BASE

On 2.6 and older since we can't address arbitrary bitranges, so we fallback to shifting the bigint. This means that after each shift, we may allocate another Integer instance.

CHUNK_BITLENGTH

We split the bigint in 32bits chunks so that individual part fits into a MRI immediate Integer.

FORMAT

Public Class Methods

from_msgpack_ext(data) click to toggle source
# File lib/msgpack/bigint.rb, line 55
def self.from_msgpack_ext(data)
  parts = data.unpack(FORMAT)

  sign = parts.shift
  sum = parts.pop.to_i

  parts.reverse_each do |part|
    sum = sum << CHUNK_BITLENGTH
    sum += part
  end

  sign == 0 ? sum : -sum
end
to_msgpack_ext(bigint) click to toggle source

Starting from Ruby 2.7 we can address arbitrary bitranges inside an Integer with Integer#[] This allows to not allocate any Integer.

# File lib/msgpack/bigint.rb, line 13
def self.to_msgpack_ext(bigint)
  members = []

  if bigint < 0
    bigint = -bigint
    members << 1
  else
    members << 0
  end

  offset = 0
  length = bigint.bit_length
  while offset < length
    members << bigint[offset, CHUNK_BITLENGTH]
    offset += CHUNK_BITLENGTH
  end

  members.pack(FORMAT)
end