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
+3
View File
@@ -0,0 +1,3 @@
module print_hej
go 1.21
+73
View File
@@ -0,0 +1,73 @@
package main
import (
"os/exec"
"strings"
"testing"
)
const scriptPath = "/Users/einand/Code/test/go/print_hej"
func runScript(decimals ...int) string {
args := []string{}
if len(decimals) > 0 {
args = append(args, string(rune(decimals[0])))
}
cmd := exec.Command(scriptPath, args...)
output, err := cmd.Output()
if err != nil {
panic(err)
}
return strings.TrimSpace(string(output))
}
func Test10Decimals(t *testing.T) {
result := runScript(10)
expected := "3.1415926535"
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}
func Test5Decimals(t *testing.T) {
result := runScript(5)
expected := "3.14159"
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}
func Test1Decimal(t *testing.T) {
result := runScript(1)
expected := "3.1"
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}
func Test100Decimals(t *testing.T) {
result := runScript(100)
expected := "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}
func TestDefault100Decimals(t *testing.T) {
result := runScript()
expected := "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}
func Test10000Decimals(t *testing.T) {
result := runScript(10000)
// Check length: "3." + 10000 digits = 10002 characters
if len(result) != 10002 {
t.Errorf("Expected 10002 characters, got %d", len(result))
}
if !strings.HasPrefix(result, "3.14159") {
t.Errorf("Result should start with 3.14159, got %s", result[:10])
}
}
+109
View File
@@ -0,0 +1,109 @@
package main
import (
"fmt"
"math/big"
"os"
"strconv"
)
func main() {
// Hämta antal decimaler från argument
decimals := 100
if len(os.Args) > 1 {
if d, err := strconv.Atoi(os.Args[1]); err == nil && d > 0 {
decimals = d
}
}
// Beräkna pi med Machins formel: pi/4 = 4*arctan(1/5) - arctan(1/239)
// Använd exakt aritmetik med big.Int
pi := calculatePiExact(decimals)
// Skriv ut resultatet
fmt.Println(formatPiExact(pi, decimals))
}
func calculatePiExact(decimals int) *big.Int {
// pi = 4 * (4*arctan(1/5) - arctan(1/239))
// Skala med 10^(decimals+10) för exakt aritmetik
scale := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(decimals+10)), nil)
atan1_5 := arctanExact(5, scale)
atan1_239 := arctanExact(239, scale)
// 4 * atan(1/5)
result := new(big.Int).Mul(big.NewInt(4), atan1_5)
// - atan(1/239)
result.Sub(result, atan1_239)
// * 4
result.Mul(result, big.NewInt(4))
return result
}
func arctanExact(x int64, scale *big.Int) *big.Int {
// 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) - ...
result := big.NewInt(0)
xBig := big.NewInt(x)
xSquared := new(big.Int).Mul(xBig, xBig)
// term = scale / x
term := new(big.Int).Div(scale, xBig)
sign := big.NewInt(1)
for n := 0; n < 100000; n++ {
// Lägg till term / (2n+1) med rätt tecken
divisor := big.NewInt(int64(2*n + 1))
contrib := new(big.Int).Div(term, divisor)
if sign.Sign() > 0 {
result.Add(result, contrib)
} else {
result.Sub(result, contrib)
}
// Nästa term: term = term / x^2
term.Div(term, xSquared)
// Växla tecken
sign.Neg(sign)
// Avbryt om termen är 0
if term.Sign() == 0 {
break
}
}
return result
}
func formatPiExact(pi *big.Int, decimals int) string {
// Konvertera till sträng
piStr := pi.String()
// pi är skalad med 10^(decimals+10), så vi behöver justera decimalpunkten
// För pi ≈ 3.14159..., pi*10^110 ≈ 314159... (110 siffror)
// Lägg till ledande noll om nödvändigt
for len(piStr) < decimals+10 {
piStr = "0" + piStr
}
// Ta första siffran, sedan decimalpunkt, sedan resten
if len(piStr) > decimals+10 {
piStr = piStr[:decimals+10]
}
// Resultatet bör vara "3" följt av decimaler
result := string(piStr[0]) + "." + piStr[1:decimals+1]
return result
}
+126
View File
@@ -0,0 +1,126 @@
package main
import (
"math/big"
"os"
"os/exec"
"strings"
"testing"
)
func TestPi10Decimals(t *testing.T) {
cmd := exec.Command("./print_hej", "10")
output, err := cmd.Output()
if err != nil {
t.Fatalf("Kunde inte köra program: %v", err)
}
result := strings.TrimSpace(string(output))
expected := "3.1415926535"
if result != expected {
t.Errorf("Fel resultat för 10 decimaler.\nFörväntade: %s\nFick: %s", expected, result)
}
}
func TestPi5Decimals(t *testing.T) {
cmd := exec.Command("./print_hej", "5")
output, err := cmd.Output()
if err != nil {
t.Fatalf("Kunde inte köra program: %v", err)
}
result := strings.TrimSpace(string(output))
expected := "3.14159"
if result != expected {
t.Errorf("Fel resultat för 5 decimaler.\nFörväntade: %s\nFick: %s", expected, result)
}
}
func TestPi1Decimal(t *testing.T) {
cmd := exec.Command("./print_hej", "1")
output, err := cmd.Output()
if err != nil {
t.Fatalf("Kunde inte köra program: %v", err)
}
result := strings.TrimSpace(string(output))
expected := "3.1"
if result != expected {
t.Errorf("Fel resultat för 1 decimal.\nFörväntade: %s\nFick: %s", expected, result)
}
}
func TestPiDefault(t *testing.T) {
cmd := exec.Command("./print_hej")
output, err := cmd.Output()
if err != nil {
t.Fatalf("Kunde inte köra program: %v", err)
}
result := strings.TrimSpace(string(output))
// Läs facit
facit, err := os.ReadFile("../facit.txt")
if err != nil {
t.Fatalf("Kunde inte läsa facit: %v", err)
}
expected := strings.TrimSpace(string(facit))
expected = strings.ReplaceAll(expected, "\n", "")[:103]
if result != expected {
t.Errorf("Fel resultat för default (100 decimaler).\nFörväntade: %s\nFick: %s", expected, result)
}
}
func TestPiInvalidInput(t *testing.T) {
cmd := exec.Command("./print_hej", "abc")
output, err := cmd.Output()
if err != nil {
t.Fatalf("Kunde inte köra program: %v", err)
}
result := strings.TrimSpace(string(output))
// Ska använda default (100 decimaler)
if !strings.HasPrefix(result, "3.1415926535") {
t.Errorf("Hanterar inte ogiltig input korrekt.\nFick: %s", result)
}
}
func TestCalculatePiExact(t *testing.T) {
pi := calculatePiExact(10)
result := formatPiExact(pi, 10)
expected := "3.1415926535"
if result != expected {
t.Errorf("calculatePiExact gav fel resultat.\nFörväntade: %s\nFick: %s", expected, result)
}
}
func TestArctanExact(t *testing.T) {
scale := new(big.Int).Exp(big.NewInt(10), big.NewInt(20), nil)
// arctan(1/5) ska vara ungefär 0.1973955598...
atan1_5 := arctanExact(5, scale)
// Kontrollera att resultatet är positivt
if atan1_5.Sign() <= 0 {
t.Errorf("arctan(1/5) ska vara positivt, fick: %v", atan1_5)
}
}
func TestFormatPiExact(t *testing.T) {
// Skapa ett pi-värde: 31415926535... (skalat med 10^10)
pi := big.NewInt(31415926535)
result := formatPiExact(pi, 10)
expected := "3.1415926535"
if result != expected {
t.Errorf("formatPiExact gav fel resultat.\nFörväntade: %s\nFick: %s", expected, result)
}
}