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
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# Rust Build Script
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$SCRIPT_DIR"
echo "=== Rust Build ==="
echo ""
# Kompilera Rust-programmet med cargo
cd src
cargo build --release
if [ $? -eq 0 ]; then
echo "✓ Kompilering lyckades!"
echo "Binär: target/release/print_hej"
echo ""
echo "För att köra:"
echo " ./bin/print_hej [decimaler]"
# Kopiera till bin/ katalogen
mkdir -p ../bin
cp target/release/print_hej ../bin/
echo "Binär kopierad till: bin/print_hej"
else
echo "✗ Kompilering misslyckades!"
exit 1
fi
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash
# Rust Unit Tests
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$SCRIPT_DIR"
echo "=== Rust Pi-beräkning Unit Tester ==="
echo ""
cd src
cargo test
exit $?
+45
View File
@@ -0,0 +1,45 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "print_hej"
version = "0.1.0"
dependencies = [
"num-bigint",
"num-traits",
]
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "print_hej"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "print_hej"
path = "print_hej.rs"
[dependencies]
num-bigint = "0.4"
num-traits = "0.2"
+58
View File
@@ -0,0 +1,58 @@
#[cfg(test)]
mod tests {
use std::process::Command;
const SCRIPT_PATH: &str = "/Users/einand/Code/test/rust/print_hej";
fn run_script(args: Option<&str>) -> String {
let mut cmd = Command::new(SCRIPT_PATH);
if let Some(arg) = args {
cmd.arg(arg);
}
let output = cmd.output().expect("Failed to execute script");
String::from_utf8_lossy(&output.stdout).trim().to_string()
}
#[test]
fn test_10_decimals() {
let result = run_script(Some("10"));
let expected = "3.1415926535";
assert_eq!(result, expected);
}
#[test]
fn test_5_decimals() {
let result = run_script(Some("5"));
let expected = "3.14159";
assert_eq!(result, expected);
}
#[test]
fn test_1_decimal() {
let result = run_script(Some("1"));
let expected = "3.1";
assert_eq!(result, expected);
}
#[test]
fn test_100_decimals() {
let result = run_script(Some("100"));
let expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679";
assert_eq!(result, expected);
}
#[test]
fn test_default_100_decimals() {
let result = run_script(None);
let expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679";
assert_eq!(result, expected);
}
#[test]
fn test_10000_decimals() {
let result = run_script(Some("10000"));
// Check length: "3." + 10000 digits = 10002 characters
assert_eq!(result.len(), 10002);
assert!(result.starts_with("3.14159"));
}
}
+85
View File
@@ -0,0 +1,85 @@
use std::env;
use num_bigint::BigUint;
use num_traits::{One, Zero};
fn main() {
// Hämta antal decimaler från argument
let args: Vec<String> = env::args().collect();
let decimals: usize = if args.len() > 1 {
args[1].parse().unwrap_or(100)
} else {
100
};
// Beräkna pi med Machins formel: pi/4 = 4*arctan(1/5) - arctan(1/239)
// Använd num-bigint för exakt aritmetik
let scale = BigUint::from(10u32).pow(decimals as u32 + 10);
let atan1_5 = arctan_big(5u32, &scale);
let atan1_239 = arctan_big(239u32, &scale);
// 4 * atan(1/5) - atan(1/239)
let mut result = &atan1_5 * 4u32;
result = &result - &atan1_239;
// * 4
result = &result * 4u32;
// Skriv ut resultatet
println!("{}", format_pi(&result, decimals));
}
fn arctan_big(x: u32, scale: &BigUint) -> BigUint {
// arctan(1/x) = 1/x - 1/(3*x^3) + 1/(5*x^5) - ...
// Med skala: scale/x - scale/(3*x^3) + scale/(5*x^5) - ...
let mut result = BigUint::zero();
let x_big = BigUint::from(x);
let x_squared = &x_big * &x_big;
// term = scale / x
let mut term = scale / &x_big;
let mut sign: i32 = 1;
let mut n: u64 = 0;
loop {
// term / (2n+1)
let divisor = BigUint::from(2u64 * n + 1);
let contrib = &term / &divisor;
if sign > 0 {
result = &result + &contrib;
} else {
result = &result - &contrib;
}
// term = term / x^2
term = &term / &x_squared;
sign = -sign;
// Avbryt om termen är 0
if term.is_zero() || n > 5000000 {
break;
}
n += 1;
}
result
}
fn format_pi(pi: &BigUint, decimals: usize) -> String {
// Konvertera till sträng
let mut digits = pi.to_string();
// Lägg till ledande noll om nödvändigt
while digits.len() < decimals + 10 {
digits.insert(0, '0');
}
// Ta första siffran, sedan decimalpunkt
let int_part = &digits[0..1];
let dec_part = &digits[1..decimals + 1];
format!("{}.{}", int_part, dec_part)
}
+152
View File
@@ -0,0 +1,152 @@
#[cfg(test)]
mod tests {
use std::process::Command;
#[test]
fn test_pi_10_decimals() {
let output = Command::new("./print_hej")
.arg("10")
.output()
.expect("Kunde inte köra program");
let result = String::from_utf8_lossy(&output.stdout).trim().to_string();
let expected = "3.1415926535";
assert_eq!(result, expected, "Fel resultat för 10 decimaler");
}
#[test]
fn test_pi_5_decimals() {
let output = Command::new("./print_hej")
.arg("5")
.output()
.expect("Kunde inte köra program");
let result = String::from_utf8_lossy(&output.stdout).trim().to_string();
let expected = "3.14159";
assert_eq!(result, expected, "Fel resultat för 5 decimaler");
}
#[test]
fn test_pi_1_decimal() {
let output = Command::new("./print_hej")
.arg("1")
.output()
.expect("Kunde inte köra program");
let result = String::from_utf8_lossy(&output.stdout).trim().to_string();
let expected = "3.1";
assert_eq!(result, expected, "Fel resultat för 1 decimal");
}
#[test]
fn test_pi_default() {
let output = Command::new("./print_hej")
.output()
.expect("Kunde inte köra program");
let result = String::from_utf8_lossy(&output.stdout).trim().to_string();
// Läs facit
let facit = std::fs::read_to_string("../facit.txt")
.expect("Kunde inte läsa facit");
let expected: String = facit.chars().take(103).collect();
assert_eq!(result, expected, "Fel resultat för default (100 decimaler)");
}
#[test]
fn test_invalid_input() {
let output = Command::new("./print_hej")
.arg("abc")
.output()
.expect("Kunde inte köra program");
let result = String::from_utf8_lossy(&output.stdout).trim().to_string();
// Ska använda default (100 decimaler)
assert!(result.starts_with("3.1415926535"), "Hanterar inte ogiltig input korrekt");
}
#[test]
fn test_calculate_pi_exact() {
let pi = calculate_pi_exact(10);
let result = format_pi(&pi, 10);
let expected = "3.1415926535";
assert_eq!(result, expected, "calculate_pi_exact gav fel resultat");
}
#[test]
fn test_arctan_exact() {
let scale = pow10(20);
let atan1_5 = arctan_exact(5, &scale);
// Kontrollera att resultatet inte är tomt
assert!(!is_zero(&atan1_5), "arctan(1/5) ska inte vara noll");
}
#[test]
fn test_format_pi() {
// Skapa ett pi-värde: 31415926535... (skalat med 10^10)
let mut pi = vec![0u32; 2];
pi[0] = 3;
pi[1] = 141592653;
let result = format_pi(&pi, 10);
let expected = "3.141592653";
assert_eq!(result, expected, "format_pi gav fel resultat");
}
#[test]
fn test_add_big() {
let a = vec![1, 500_000_000];
let b = vec![2, 600_000_000];
let result = add_big(&a, &b);
// 1*10^9 + 500000000 + 2*10^9 + 600000000 = 4100000000
// = 4 * 10^9 + 100000000
assert_eq!(result[0], 4);
assert_eq!(result[1], 100_000_000);
}
#[test]
fn test_subtract_big() {
let a = vec![5, 700_000_000];
let b = vec![2, 300_000_000];
let result = subtract_big(&a, &b);
// 5*10^9 + 700000000 - 2*10^9 - 300000000 = 3400000000
// = 3 * 10^9 + 400000000
assert_eq!(result[0], 3);
assert_eq!(result[1], 400_000_000);
}
#[test]
fn test_multiply() {
let a = vec![1, 500_000_000];
let result = multiply(&a, 2);
// 1*10^9 + 500000000 * 2 = 3000000000
// = 3 * 10^9
assert_eq!(result[0], 3);
assert_eq!(result[1], 0);
}
#[test]
fn test_divide_big() {
let a = vec![1, 0]; // 10^9
let result = divide_big(&a, 2);
// 10^9 / 2 = 500000000
assert_eq!(result[0], 0);
assert_eq!(result[1], 500_000_000);
}
}