@rbxts/bint
v0.3.0
Published
Arbitrary-precision signed integer library for Luau with operator support, multiple algorithms, and TypeScript typings.
Downloads
428
Maintainers
Readme
bint
Arbitrary-precision signed integer library for Luau.
bint stores integers as little-endian base-2^24 limbs, so values can grow without fixed-width overflow. It supports idiomatic operators (+, -, *, //, %, ^, comparisons), plus a lower-level core API with mutating and non-mutating functions.
v0.3.0 renames all conversion helpers to a uniform to_*/from_* convention, adds lossy scientific-notation decomposition (to_sci), and fixes several Burnikel-Ziegler division edge cases.
Latest release: 0.3.0.
Features
- Arbitrary-precision signed integers.
- Constructors from Lua numbers, strings (base 2-36), and raw limb arrays.
- Conversion to/from strings and byte strings (little/big endian).
- Floor and truncated division APIs.
- Integer exponentiation and integer square root.
- Multiple multiplication/division algorithms chosen by operand size.
- Luau + TypeScript declaration file support (
src/index.d.ts).
Usage
local mod = require(path.to.bint)
local bint = mod.bint
local core = mod.core
local a = bint("123456789012345678901234567890")
local b = bint.from_int(42)
local sum = a + b
local prod = a * b
local q, r = core.divmod(a, b) -- floor division
print(sum:to_string()) -- method form
print(bint.to_string(prod)) -- function form
print(q, r)bint(v) is an alias for bint.new(v).
For roblox-ts / TypeScript users, the standard non-mutating arithmetic/comparison operations are also available as instance methods (for example a:add(b), a:mul(b), a:divmod(b)), which avoids relying on Luau operator metamethod syntax in typed code. Mutating operations remain on core.
API summary
Constructors
bint.from_int(n: number): Bint(converts the current Luaunumbervalue)bint.from_string(s: string, base?: number): Bintbint.from_limbs(limbs: {number}, signum?: -1 | 0 | 1): Bintbint.zero(): Bintbint.one(): Bintbint.new(v: Bint | number | string): Bintbint(v)(callable module alias)
Conversion helpers
bint.to_string(a: Bint, base?: number): stringbint.to_number(a: Bint): numberbint.to_sci(a: Bint): (number, number)— lossy scientific notation(coefficient, exponent)bint.to_le(a: Bint, trim?: boolean): stringbint.to_be(a: Bint, trim?: boolean): stringbint.from_le(s: string): Bintbint.from_be(s: string): Bint
core operations
core provides low-level signed arithmetic on canonical Bint values. No input coercion or validation is performed — arguments must already be Bint instances. Reach for core when you need mutating operations (_mut variants) or want to avoid repeated allocation; use the bint class for everyday ergonomic use.
- Comparison:
cmp,eq,lt,le - Sign:
abs,abs_mut,neg,neg_mut - Arithmetic:
add,add_mut,sub,sub_mut,mul,mul_mut - Division (floor):
divmod,idiv,mod - Division (truncated):
tdivmod,tdiv,tmod - Other:
pow,sqrt,lshift,rshift,lshift_words,rshift_words
algorithms entry points
Direct algorithm entry points that bypass automatic threshold dispatch at the top-level call. Each function has the same contract as its core counterpart and forces the named top-level algorithm regardless of operand size; recursive subproblems may still dispatch/fallback internally. Useful for benchmarking threshold crossover points and validating specific algorithm entry paths.
- Multiplication:
algorithms.mul_basecase,algorithms.mul_karatsuba,algorithms.mul_toom3 - Division:
algorithms.div_knuth,algorithms.div_burnikel - Square root:
algorithms.sqrt_newton,algorithms.sqrt_karatsuba
Operator behavior
Supported metamethods:
+,-,*,//,%,^, unary-==,<,<=tostring(x)andx:to_string()#xreturns decimal digit count of magnitude
/ is intentionally unsupported and throws an error. Use // for integer division.
Semantics and caveats
bint.from_int(n)converts the already-represented Luaunumberexactly; Luau numbers are IEEE-754 doubles, so integer literals above2^53may already be rounded. Usebint.from_string(...)for exact large integer literals.bint.from_string/bint.to_stringsupport bases2..36.core.divmodand//use floor division semantics.core.tdivmoduses truncated (toward zero) semantics.core.rshift(a, n)uses arithmetic (sign-preserving) semantics, equivalent tofloor(a / 2^n).core.lshift_words/core.rshift_wordsare limb-count shifts (base-2^24words), not bit shifts.core.sqrt(a)returns0fora <= 0.bint.to_le/bint.to_beserialize magnitude only (sign is not encoded).bint.to_numberis exact only up to magnitude2^53.bint.to_sciis lossy by design; useful for display/formatting, not exact arithmetic.
Running tests
lune run libs/specs # full suite (all tags)
lune run libs/specs --tag fast # quick local validation
lune run libs/specs --tag full # CI-style: fast + full tests
lune run libs/specs --tag stress # everything including slow/deep checks
lune run libs/specs --list-tags # show available tags and countsChangelog format
This repository uses the Keep a Changelog structure.
