Initial commit: Pi calculation benchmark with 34 languages

- Added implementations for: bash, brainfuck, c, cpp, crystal, csharp, d, dart, elixir, erlang, fortran, go, haskell, java, javascript, julia, kotlin, objective-c, scala, typescript, lua, nim, odin, perl, php, python, r, ruby, rust, swift, zig, assembly, vimscript, wolfram
- All implementations use Machin's formula: π/4 = 4*arctan(1/5) - arctan(1/239)
- Build system with ./build.sh, test system with ./test.sh
- Performance testing with ./run_all.sh
- Comprehensive README.md explaining performance differences
- Test framework verifies correctness against known π values
This commit is contained in:
Ein Anderssono
2026-04-23 00:26:18 +02:00
commit 54d2fecee0
182 changed files with 17471 additions and 0 deletions
+182
View File
@@ -0,0 +1,182 @@
-- Simple BigInt implementation using base 10^9
local BigInt = {}
BigInt.__index = BigInt
function BigInt.new(value)
local self = setmetatable({}, BigInt)
if type(value) == "number" then
if value == 0 then
self.digits = {0}
else
self.digits = {math.abs(value)}
end
else
self.digits = {0}
end
return self
end
function BigInt:add(other)
local carry = 0
local maxLen = math.max(#self.digits, #other.digits)
for i = 1, maxLen do
local a = self.digits[i] or 0
local b = other.digits[i] or 0
local sum = a + b + carry
self.digits[i] = sum % 1000000000
carry = math.floor(sum / 1000000000)
end
if carry > 0 then
table.insert(self.digits, carry)
end
end
function BigInt:subtract(other)
local borrow = 0
for i = 1, #self.digits do
local a = self.digits[i]
local b = other.digits[i] or 0
local diff = a - b - borrow
if diff < 0 then
diff = diff + 1000000000
borrow = 1
else
borrow = 0
end
self.digits[i] = diff
end
-- Remove leading zeros
while #self.digits > 1 and self.digits[#self.digits] == 0 do
table.remove(self.digits)
end
end
function BigInt:multiply(scalar)
local result = BigInt.new(0)
result.digits = {}
local carry = 0
for i = 1, #self.digits do
local prod = self.digits[i] * scalar + carry
result.digits[i] = prod % 1000000000
carry = math.floor(prod / 1000000000)
end
if carry > 0 then
table.insert(result.digits, carry)
end
return result
end
function BigInt:divide(divisor)
local result = BigInt.new(0)
result.digits = {}
local remainder = 0
for i = #self.digits, 1, -1 do
local cur = remainder * 1000000000 + self.digits[i]
result.digits[i] = math.floor(cur / divisor)
remainder = cur % divisor
end
-- Remove leading zeros
while #result.digits > 1 and result.digits[#result.digits] == 0 do
table.remove(result.digits)
end
return result
end
function BigInt:isZero()
return #self.digits == 1 and self.digits[1] == 0
end
function BigInt:toString()
local result = ""
for i = #self.digits, 1, -1 do
if i == #self.digits then
result = result .. self.digits[i]
else
result = result .. string.format("%09d", self.digits[i])
end
end
return result
end
-- Power of 10
local function pow10(exp)
local result = BigInt.new(1)
for i = 1, exp do
result = result:multiply(10)
end
return result
end
-- Calculate arctan(1/x) using Taylor series
local function arctan(x, decimals)
local scale = pow10(decimals + 10)
local x_squared = x * x
local term = scale:divide(x)
local result = BigInt.new(0)
local n = 0
while not term:isZero() do
local divisor = 2 * n + 1
local contrib = term:divide(divisor)
if n % 2 == 0 then
result:add(contrib)
else
result:subtract(contrib)
end
term = term:divide(x_squared)
n = n + 1
end
return result
end
-- Calculate pi using Machin's formula
local function calculate_pi(decimals)
local atan1_5 = arctan(5, decimals)
local atan1_239 = arctan(239, decimals)
-- pi = 16*arctan(1/5) - 4*arctan(1/239)
local pi16 = atan1_5:multiply(16)
local pi4 = atan1_239:multiply(4)
pi16:subtract(pi4)
local pi_str = pi16:toString()
-- Format with decimal point
local result = "3."
local start = 2
for i = 0, decimals - 1 do
if start + i <= #pi_str then
result = result .. string.sub(pi_str, start + i, start + i)
else
result = result .. "0"
end
end
return result
end
-- Main
local decimals = 100
if #arg > 0 then
decimals = tonumber(arg[1]) or 100
end
print(calculate_pi(decimals))
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env lua
-- Unit tests for Lua pi calculation using busted
local SCRIPT_PATH = "/Users/einand/Code/test/lua/print_hej.lua"
local function run_script(...)
local args = {...}
local cmd = "lua " .. SCRIPT_PATH
for _, arg in ipairs(args) do
cmd = cmd .. " " .. tostring(arg)
end
local handle = io.popen(cmd, "r")
local result = handle:read("*a")
handle:close()
-- Trim newline
result = result:gsub("\n$", "")
return result
end
describe("Pi calculation", function()
it("calculates 10 decimals", function()
local result = run_script(10)
local expected = "3.1415926535"
assert.are.equal(expected, result)
end)
it("calculates 5 decimals", function()
local result = run_script(5)
local expected = "3.14159"
assert.are.equal(expected, result)
end)
it("calculates 1 decimal", function()
local result = run_script(1)
local expected = "3.1"
assert.are.equal(expected, result)
end)
it("calculates 100 decimals", function()
local result = run_script(100)
local expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
assert.are.equal(expected, result)
end)
it("calculates default 100 decimals", function()
local result = run_script()
local expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
assert.are.equal(expected, result)
end)
it("calculates 10000 decimals", function()
local result = run_script(10000)
-- Check length: "3." + 10000 digits = 10002 characters
assert.are.equal(10002, #result)
assert.is_true(string.sub(result, 1, 7) == "3.14159")
end)
end)