BaseSystem
For versioned four-family numeral parsing, exact repeating expansions in balanced or negative bases, and bounded conversion evidence, see NumeralSystem. It is a separate workspace API; the BaseSystem methods documented here remain unchanged.
BaseSystem defines an ordered single-character digit alphabet. It converts integers to and from that alphabet and supplies digit systems for rational formatting.
Construct a system
import { BaseSystem } from "@ratmath/core";
const custom = new BaseSystem("abc", "ABC digits");
custom.base; // 3
custom.radix; // 3
custom.characters; // ["a", "b", "c"]
custom.charMap.get("c"); // 2
custom.name; // "ABC digits"The first character has value zero, the second value one, and so on. The constructor accepts a string or an array and requires at least two unique single Unicode characters. It does not expand range syntax such as "0-9a-f".
+ - * / ^ ! ( ) [ ] : . # ~ are in BaseSystem.RESERVED_SYMBOLS and cannot be digits because they conflict with RatMath/RiX notation. A host that quotes the complete digit stream can opt in with { allowReserved: true } and should check requiresQuoting. The characters array and charMap getters return copies.
Signed, balanced, and bijective systems
The optional third constructor argument changes the signed radix or the value of the first digit. Digit values remain consecutive.
const balanced = new BaseSystem("T01", "Balanced ternary", {
radix: 3,
digitOffset: -1,
});
const negabinary = new BaseSystem("01", "Negabinary", { radix: -2 });
const bijective = new BaseSystem("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "Bijective 26", {
radix: 26,
digitOffset: 1,
});
balanced.fromDecimal(-5n); // "T11"
negabinary.fromDecimal(-5n); // "1111"
bijective.fromDecimal(27n); // "AA"base is the alphabet size, while radix is the signed positional radix and digitOffset is the first character’s value. supportsPositionalFractions is true only for the ordinary configuration where radix === base and the first digit means zero. Nonstandard systems support exact integer conversion and numerator/denominator formatting. Repeating fractional expansions, period calculation, and certified radix-prefix construction reject them because those algorithms require ordinary nonnegative fractional-place digits. A bijective system has no representation for zero and throws if asked to format it.
Conversion and inspection
| Method | Result |
|---|---|
getChar(value) |
Digit at an in-range safe integer value; otherwise throws |
toDecimal(text) |
Signed digit string converted to bigint |
fromDecimal(value) |
bigint converted to a signed digit string |
isValidString(text) |
Whether the optional-minus string contains only digits in the system |
getMinDigit() |
Zero digit |
getMaxDigit() |
Highest-value digit |
toString() |
Human-readable name and alphabet preview |
equals(other) |
Equality of the ordered digit alphabets |
withCaseSensitivity(flag) |
this for true; a lowercased/deduplicated system for false |
BaseSystem.HEXADECIMAL.toDecimal("ff"); // 255n
BaseSystem.BINARY.fromDecimal(-10n); // "-1010"
BaseSystem.OCTAL.isValidString("789"); // false
BaseSystem.HEXADECIMAL.getChar(15); // "f"toDecimal("-") throws because a sign alone is not a numeral. Array entries containing more than one Unicode character and fractional, non-finite, or unsafe getChar indexes also throw.
Case folding preserves signed-radix options when no digits collapse. When upper- and lowercase digits collapse to the same character, the result becomes an ordinary positional system whose base is the deduplicated alphabet size.
Roman numerals are exposed as a custom alphabet named ROMAN, but conversion is positional base-7 conversion; it does not implement subtractive Roman numeral grammar.
Presets
| Property | Base |
|---|---|
BINARY |
2 |
TERNARY |
3 |
QUATERNARY |
4 |
QUINARY |
5 |
SEPTENARY |
7 |
OCTAL |
8 |
DECIMAL |
10 |
DUODECIMAL |
12 |
HEXADECIMAL |
16 |
VIGESIMAL |
20 |
BASE36 |
36 |
BASE60 |
60 |
BASE62 |
62 |
BASE64 |
64 |
ROMAN |
7 custom digits |
Factories
BaseSystem.fromBase(base, name?) builds the standard 0-9, a-z, A-Z ordering for bases 2 through 62.
BaseSystem.fromBase(16).equals(BaseSystem.HEXADECIMAL); // trueBaseSystem.createPattern(pattern, size, name?) accepts:
| Pattern | Limit and ordering |
|---|---|
"alphanumeric" |
base 2–62 using fromBase |
"digits-only" |
up to 10, starting with 0 |
"letters-only" |
up to 52, a-z then A-Z |
"uppercase-only" |
up to 26, A-Z |
Unknown patterns or sizes beyond a pattern’s alphabet throw.
Prefix registry
The registry is metadata for parser integrations; the core number parser does not itself parse prefixed values.
| Method | Behavior |
|---|---|
registerPrefix(prefix, system) |
Register one ASCII letter |
unregisterPrefix(prefix) |
Remove its exact entry |
hasExactPrefix(prefix) |
Exact-case membership |
getSystemForPrefix(prefix) |
Exact match, then mostly case-insensitive lookup |
getPrefixForSystem(system) |
First registered prefix for an equal alphabet |
Built-in prefixes are b (2), t (3), q (4), f (5), s (7), o (8), d (12), x (16), v (20), u (36), m (60), and y (64). Uppercase D is reserved and returns null; a missing prefix otherwise returns undefined.
Tagged JSON preserves radix, digitOffset, and allowReserved. Passing reviveCoreValue to JSON.parse restores the same conversion behavior.
BaseSystem.getSystemForPrefix("x").equals(BaseSystem.HEXADECIMAL); // true
BaseSystem.getPrefixForSystem(BaseSystem.BINARY); // "b"
BaseSystem.getSystemForPrefix("D"); // nullVersioned numeral systems
NumeralSystem is the bounded multi-token and signed-positional companion to BaseSystem. It does not change the existing prefix registry or BaseSystem semantics. Construct it with {kind, radix, tokens}; kind is ordinary, multiToken, balanced or negative. toJSON() records schema ratmath.numeral-system@1; new NumeralSystem(record) validates an import. Labels and host parser registration belong to RiX.
parse(source) returns an exact Rational. format(value,{maxDigits,mode}) returns an expansion record, exact source, integer carry steps, remainder steps, period and explicit exhaustion. normalize parses then formats; places returns exact weights/contributions; locale applies reversible point/group separators. All alphabets are prefix-free and punctuation-safe. No algorithm uses binary floating-point approximations to determine digits or equality. Families, grammar, limits and examples are specified in the RiX Radix numeral-systems guide.