Skip to content

Number Base Converter — Java source

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

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

// number-base — Java port: arbitrary-precision base conversion (bases 2-36).
import java.math.BigInteger;

/** Arbitrary-precision base conversion, ported from src/lib/numberBase.ts. */
public final class NumberBase {

    private static final String DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz";

    private NumberBase() {}

    /** Map a lowercase character to its value; -1 when not a digit. */
    private static int digitValue(char c) {
        if (c >= '0' && c <= '9') return c - '0';
        if (c >= 'a' && c <= 'z') return c - 'a' + 10;
        return -1;
    }

    /** Parse s in base (2-36); null on invalid input. A leading sign is
     *  honored, and a radix prefix is stripped only when it agrees with the
     *  base — so "0xFF" parses in base 16 but is rejected in base 10. */
    public static BigInteger parseBigInt(String s, int base) {
        if (base < 2 || base > 36) return null;
        s = s.trim().toLowerCase();
        boolean neg = false;
        if (s.startsWith("-")) { neg = true; s = s.substring(1); }
        else if (s.startsWith("+")) s = s.substring(1);
        if ((s.startsWith("0x") && base == 16) || (s.startsWith("0b") && base == 2)
                || (s.startsWith("0o") && base == 8)) s = s.substring(2);
        if (s.isEmpty()) return null;
        BigInteger result = BigInteger.ZERO, b = BigInteger.valueOf(base);
        for (char c : s.toCharArray()) {
            int d = digitValue(c);
            if (d < 0 || d >= base) return null;
            result = result.multiply(b).add(BigInteger.valueOf(d)); // Horner
        }
        return neg ? result.negate() : result;
    }

    /** Render value in base (2-36); "" for an unsupported base, matching the
     *  TS lib. The sign of zero is never emitted. */
    public static String formatBigInt(BigInteger value, int base) {
        if (base < 2 || base > 36) return "";
        if (value.signum() == 0) return "0";
        BigInteger v = value.abs(), b = BigInteger.valueOf(base);
        StringBuilder out = new StringBuilder();
        while (v.signum() > 0) {
            BigInteger[] qr = v.divideAndRemainder(b); // peel LSD first
            out.append(DIGITS.charAt(qr[1].intValue()));
            v = qr[0];
        }
        if (value.signum() < 0) out.append('-');
        return out.reverse().toString();
    }

    /** value(fromBase) -> toBase; null when it does not parse. */
    public static String convertBase(String value, int fromBase, int toBase) {
        BigInteger n = parseBigInt(value, fromBase);
        return n == null ? null : formatBigInt(n, toBase);
    }
}

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 →