module MessagePack::Bigint

def self.from_msgpack_ext(data)

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

def self.to_msgpack_ext(bigint)

This allows to not allocate any Integer.
Starting from Ruby 2.7 we can address arbitrary bitranges inside an Integer with Integer#[]
Ruby 2.7 and newer
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

def self.to_msgpack_ext(bigint)

def self.to_msgpack_ext(bigint)
  members = []
  if bigint < 0
    bigint = -bigint
    members << 1
  else
    members << 0
  end
  while bigint > 0
    members << (bigint & BASE)
    bigint = bigint >> CHUNK_BITLENGTH
  end
  members.pack(FORMAT)
end