Skip to content

Number Base Converter — Ruby source

Convert numbers between binary, octal, decimal and hexadecimal. BigInt-powered, so it handles arbitrarily large values without precision loss.

This is the Ruby implementation — the same logic the interactive tool runs, in a shareable, citable form.

# number-base — Ruby port: arbitrary-precision base conversion (bases 2-36).

DIGITS = '0123456789abcdefghijklmnopqrstuvwxyz'

# Map a lowercase character to its value; -1 when not a digit.
def digit_value(ch)
  return ch.ord - 48 if ch.between?('0', '9')
  return ch.ord - 87 if ch.between?('a', 'z')

  -1
end

# Parse +s+ in +base+ (2-36); nil on invalid input. A radix prefix is
# stripped only when it agrees with the base — so "0xFF" parses in base 16
# but is rejected in base 10. Ruby Integers are arbitrary precision, so
# results are exact for inputs of any length.
def parse_bigint(s, base)
  return nil unless base.between?(2, 36)

  t = s.strip.downcase
  neg = false
  case t
  when /^-/ then neg, t = true, t[1..]
  when /^\+/ then t = t[1..]
  end
  t = t[2..] if (t.start_with?('0x') && base == 16) ||
               (t.start_with?('0b') && base == 2) ||
               (t.start_with?('0o') && base == 8)
  return nil if t.empty?

  result = 0
  t.each_char do |ch| # Horner's method
    d = digit_value(ch)
    return nil if d.negative? || d >= base

    result = result * base + d
  end
  neg ? -result : result
end

# Render +value+ in +base+ (2-36); '' for an unsupported base, matching the
# TS lib. The sign of zero is never emitted.
def format_bigint(value, base)
  return '' unless base.between?(2, 36)
  return '0' if value.zero?

  neg = value.negative?
  v = value.abs
  digits = []
  while v.positive? # divmod peels the least-significant digit each pass
    v, rem = v.divmod(base)
    digits << DIGITS[rem]
  end
  digits << '-' if neg
  digits.reverse.join
end

# value(+from_base+) -> +to_base+; nil when it does not parse.
def convert_base(value, from_base, to_base)
  n = parse_bigint(value, from_base)
  return nil if n.nil?

  format_bigint(n, to_base)
end

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →