Skip to content

CrabGuy/APInt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

41 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

A PInt ๐Ÿบ: Arbitrary-Precision Integer Library for Lua (and Roblox)

APInt is an Arbitrary Precision Integer library, built to calculate large numbers without losing a single bit of precision. ๐Ÿ”ข

This library is engineered to be effortlessly easy to use, integrating as seamlessly as possible into existing Lua projects by overloading standard arithmetic metatables.

Features ๐ŸŒŸ

  • ๐Ÿง  Arbitrary-Precision Integers: Create and manipulate integers far larger than Lua's maximum int value.

All standard arithmetic operators are overloaded:

  • โž• Operations:
    • Addition (+)
    • Subtraction (-)
    • Multiplication (*)
    • Division (/) (floor division)
    • Modulo (%)
    • Exponentiation (^)
    • Unary Minus (-)
  • โš–๏ธ Comparison Operators:
    • Less Than (<)
    • Equality (==)
    • (Greater than, less than or equal to, etc., also work, inferred from < and ==)
  • ๐Ÿ“œ String Conversion: tostring method also works.
  • โš™๏ธ Additional Operations:
    • Bitwise-like Shifts: Implemented for internal use (__lsl and __lsr are available in the source, though not aliased to << or >> to maintain Lua 5.2 standards).
    • ๐Ÿ”ง Flexible Type Handling: Configure the library to operate in different modes (STRICT, WARNING, NOT-STRICT) to manage operations with mixed APInt and standard number types.

Getting Started ๐Ÿš€

To use APInt ๐Ÿบ, simply require the APInt.lua file in your project.

local APInt = require("APInt")

If you're on Roblox: just make the library a ModuleScript and require it from a Local or Server Script.

Or also on wally (a roblox package manager) thanks to Vran-n!

[APInt wally package]

Creating New Large Integers ๐Ÿ”ข

You can create new arbitrary-precision integers from a number, a string, or even another APInt object (a table of integers between 0 and BASE).

-- From a number
local a = APInt.new(12345)
local b = APInt(98765) -- You can also call the library object directly!

-- From a string for massive numbers
local very_large_number = APInt.new("123456789012345678901234567890")
local another_large_one = APInt("987654321098765432109876543210")

Usage Snippets ๐Ÿ’ก

Arithmetic Operations ๐Ÿงฎ

All the standard arithmetic operators work seemlessly as you'd expect.

local APInt = require("APInt")

local a = APInt("23456789012345678901")
local b = APInt("98765432109876543210")

-- Addition
local sum = a + b
print("Sum:", sum)

-- Subtraction
local difference = b - a
print("Difference:", difference)

-- Multiplication
local product = APInt(2)^APInt(256)
print("Product:", product)

-- Division
local quotient, remainder = a / b
print("Quotient:", quotient)
print("Remainder:", remainder)

-- Modulo
local mod = b % a
print("Modulo:", mod)

-- Exponentiation
local power = APInt(5)^APInt(100)
print("5^100:", power)

Comparisons ๐Ÿ‘€

local APInt = require("APInt")

local a = APInt("100000000000000000000")
local b = APInt("100000000000000000001")

if a < b then
    print("a is less than b")
end

if a == a then
    print("a is equal to itself")
end

String Conversion ๐Ÿ”„

You can convert APInt objects to strings for printing or serialization.

local APInt = require("APInt")

local large_number = APInt(2)^APInt(128)

-- Implicitly calls __tostring
print("2^128 is: " .. large_number)

local as_string = tostring(large_number)
print(as_string)

Configuration ๐Ÿ› ๏ธ

You can tweak the library's mode for handling non-APInt types in operations.

  • "NOT-STRICT" (default): Automatically converts numbers to APInt. โœ…
  • "WARNING": Converts numbers but gives you a heads-up with a warning. โš ๏ธ
  • "STRICT": Throws an error if an operation involves a non-APInt type. ๐Ÿ›‘
local APInt = require("APInt")

APInt.MODE = "STRICT"

local a = APInt(100)
-- This will now throw an error instead of silently converting 50!
local result = a + 50

Performance Showdown ๐ŸŽ๏ธ๐Ÿ’จ

The Competitor

APInt competes with the BigNum library by the great programmer Validark. It has equal or better performance for correct results in Roblox Studio, which I am satisfied with!

Blazing-Fast Performance ๐Ÿ”ฅ

The benchmark file is in the repository, so you can test it on your own machine! (You'll need the BigNum and APInt libraries in the same directory).

The results files are also in the repository: "benchmark_results_computer" for tests on my computerโ„ข and "benchmark_results_studio" for tests in Roblox Studio.

Here are some of the most egregious results:

๐Ÿ–ฅ๏ธ Computer Benchmark

Operation BigNum Time APInt Time Speedup
Creation (.new) 1.003874 0.009388 ~107x
Division (Large) 175.193368 49.426132 ~3.5x
Modulo (Large) 170.684935 48.997882 ~3.5x
To String (Large) 152.764841 11.557140 ~13.2x

๐Ÿ•น๏ธ Roblox Studio Benchmark

Operation BigNum Time APInt Time Speedup
Creation (.new) 0.166527 0.020295 ~8.2x
Division (Large) 6.890840 1.265368 ~5.4x
Modulo (Large) 7.019249 1.278361 ~5.5x
To String (Large) 6.511121 0.333968 ~19.5x

More Info โ„น๏ธ

Implementation Details

The numbers are stored as a table (array) of numbers in base 2^52 by default, with the last number also storing the sign. This structure takes advantage of Lua's float64 number type without sacrificing precision. The table is variable-sized, and every number is immutable. The algorithms used are linked in the source code!

Testing

The library is unit-tested using Busted in test.lua. It runs as a standalone file with Lua 5.2 (with Busted installed).

Additional info

  • This library aims to replicate the simplicity and elegance of how Python handles big integers. ๐Ÿ
  • I implemented karatsuba's algorithm for multiplication (and division) but the performance was worse even for big numbers so it got cut in the final release.
  • My favourite beer is Guinness

Missing Features (Feel free to fork! ๐Ÿด)

  • The library was built for Roblox games but doesn't yet leverage Roblox's buffer library, which could be faster.

About

Arbitrary precision integer library for lua and roblox games.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages