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:
@@ -0,0 +1,65 @@
|
||||
-module(pi_test).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
-define(SCRIPT_PATH, "/Users/einand/Code/test/erlang/print_hej").
|
||||
|
||||
run_script(Args) ->
|
||||
Cmd = ?SCRIPT_PATH ++ " " ++ Args,
|
||||
Port = open_port({spawn, Cmd}, [stream, exit_status]),
|
||||
receive
|
||||
{Port, {data, Output}} ->
|
||||
port_close(Port),
|
||||
string:trim(Output, trailing, "\n");
|
||||
{Port, {exit_status, _Status}} ->
|
||||
port_close(Port),
|
||||
""
|
||||
after 5000 ->
|
||||
port_close(Port),
|
||||
""
|
||||
end.
|
||||
|
||||
run_script_no_args() ->
|
||||
Cmd = ?SCRIPT_PATH,
|
||||
Port = open_port({spawn, Cmd}, [stream, exit_status]),
|
||||
receive
|
||||
{Port, {data, Output}} ->
|
||||
port_close(Port),
|
||||
string:trim(Output, trailing, "\n");
|
||||
{Port, {exit_status, _Status}} ->
|
||||
port_close(Port),
|
||||
""
|
||||
after 5000 ->
|
||||
port_close(Port),
|
||||
""
|
||||
end.
|
||||
|
||||
test_10_decimals_test() ->
|
||||
Result = run_script("10"),
|
||||
Expected = "3.1415926535",
|
||||
?assertEqual(Expected, Result).
|
||||
|
||||
test_5_decimals_test() ->
|
||||
Result = run_script("5"),
|
||||
Expected = "3.14159",
|
||||
?assertEqual(Expected, Result).
|
||||
|
||||
test_1_decimal_test() ->
|
||||
Result = run_script("1"),
|
||||
Expected = "3.1",
|
||||
?assertEqual(Expected, Result).
|
||||
|
||||
test_100_decimals_test() ->
|
||||
Result = run_script("100"),
|
||||
Expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679",
|
||||
?assertEqual(Expected, Result).
|
||||
|
||||
test_default_100_decimals_test() ->
|
||||
Result = run_script_no_args(),
|
||||
Expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679",
|
||||
?assertEqual(Expected, Result).
|
||||
|
||||
test_10000_decimals_test() ->
|
||||
Result = run_script("10000"),
|
||||
% Check length: "3." + 10000 digits = 10002 characters
|
||||
?assertEqual(10002, length(Result)),
|
||||
?assert(lists:prefix("3.14159", Result)).
|
||||
@@ -0,0 +1,64 @@
|
||||
-module(print_hej).
|
||||
-export([main/1, pow/2]).
|
||||
|
||||
main(Args) ->
|
||||
Decimals = case Args of
|
||||
[] -> 100;
|
||||
[X | _] ->
|
||||
case string:to_integer(X) of
|
||||
{D, _} when D > 0 -> D;
|
||||
_ -> 100
|
||||
end
|
||||
end,
|
||||
|
||||
Pi = calculate_pi(Decimals),
|
||||
PiStr = format_pi(Pi, Decimals),
|
||||
io:format("~s~n", [PiStr]),
|
||||
erlang:halt(0).
|
||||
|
||||
% Calculate arctan(1/x) using Taylor series
|
||||
% arctan(1/x) = 1/x - 1/(3*x^3) + 1/(5*x^5) - ...
|
||||
arctan(X, Decimals) ->
|
||||
Scale = pow(10, Decimals + 10),
|
||||
XSquared = X * X,
|
||||
Term = Scale div X, % First term: scale / x
|
||||
arctan_iter(XSquared, Term, 0, 0, Decimals).
|
||||
|
||||
arctan_iter(_XSquared, Term, N, Result, Decimals) when Term == 0; N > Decimals * 3 ->
|
||||
Result;
|
||||
arctan_iter(XSquared, Term, N, Result, Decimals) ->
|
||||
Divisor = 2 * N + 1,
|
||||
Contrib = Term div Divisor,
|
||||
NewResult = case N rem 2 of
|
||||
0 -> Result + Contrib;
|
||||
1 -> Result - Contrib
|
||||
end,
|
||||
NewTerm = Term div XSquared, % Divide by x² each iteration
|
||||
arctan_iter(XSquared, NewTerm, N + 1, NewResult, Decimals).
|
||||
|
||||
% Calculate pi using Machin's formula
|
||||
% pi/4 = 4*arctan(1/5) - arctan(1/239)
|
||||
calculate_pi(Decimals) ->
|
||||
Atan1_5 = arctan(5, Decimals),
|
||||
Atan1_239 = arctan(239, Decimals),
|
||||
16 * Atan1_5 - 4 * Atan1_239.
|
||||
|
||||
% Format pi with decimal point
|
||||
format_pi(Pi, Decimals) ->
|
||||
PiStr = integer_to_list(Pi),
|
||||
% Pad with leading zeros if needed
|
||||
PiStr2 = case length(PiStr) < Decimals + 10 of
|
||||
true -> string:left(PiStr, Decimals + 10, $0);
|
||||
false -> PiStr
|
||||
end,
|
||||
"3." ++ string:substr(PiStr2, 2, Decimals).
|
||||
|
||||
% Power function for integers
|
||||
pow(Base, Exp) when Exp >= 0 ->
|
||||
pow_iter(Base, Exp, 1).
|
||||
|
||||
pow_iter(_Base, 0, Acc) -> Acc;
|
||||
pow_iter(Base, Exp, Acc) when Exp rem 2 == 0 ->
|
||||
pow_iter(Base * Base, Exp div 2, Acc);
|
||||
pow_iter(Base, Exp, Acc) ->
|
||||
pow_iter(Base, Exp - 1, Acc * Base).
|
||||
Reference in New Issue
Block a user