diff --git a/tests/bench/pi.c b/tests/bench/pi.c new file mode 100644 index 0000000000..beeeb0c372 --- /dev/null +++ b/tests/bench/pi.c @@ -0,0 +1,91 @@ +#include +#include + +void ComputePi(int numdigits, char* pi) +{ + int alength = 10 * numdigits / 3; + int* a = (int*) malloc(alength * sizeof(int)); + int piLength = 0; + int nines = 0; + int predigit = 0; + int i, j; + for(i = 0; i < alength; ++i) + a[i] = 2; + + for (j = 0; j < numdigits; ++j) + { + int q = 0; + int p = 2 * alength - 1; + for (i = alength; --i >= 0; ) + { + int x = 10*a[i] + q*(i+1); + a[i] = x % p; + q = x / p; + p -= 2; + } + + a[0] = q % 10; + q /= 10; + if (q == 9) + ++nines; + else if (q == 10) + { + int k; + pi[piLength] = (char) (predigit + 1 + '0'); + for (k = 1; k <= nines; ++k) + pi[piLength+k] = '0'; + piLength += nines + 1; + predigit = 0; + nines = 0; + } + else + { + int k; + pi[piLength] = (char)(predigit + '0'); + predigit = q; + for (k = 1; k <= nines; ++k) + pi[piLength + k] = '9'; + piLength += nines + 1; + nines = 0; + } + } + pi[piLength] = (char)(predigit + '0'); + pi[piLength+1] = '\0'; + + free(a); +} + +int main(int argc, char** argv) +{ + int numdigits; + char* pi; + + if (argc <= 1) + { + fprintf(stderr, "usage: pi #DIGITS [FILE]"); + return 1; + } + + numdigits = atoi(argv[1]); + pi = (char*) malloc(numdigits+1); + ComputePi(numdigits, pi); + + if (argc > 2) + { + FILE* fp = fopen(argv[2], "w"); + if (fp == NULL) + { + fprintf(stderr, "Cannot open %s\n", argv[2]); + return 2; + } + fputs(pi, fp); + fputc('\n', fp); + fclose(fp); + } + else + puts(pi); + + free(pi); + + return 0; +} \ No newline at end of file diff --git a/tests/bench/pi.pp b/tests/bench/pi.pp new file mode 100644 index 0000000000..5e39227166 --- /dev/null +++ b/tests/bench/pi.pp @@ -0,0 +1,96 @@ +program pi; + +{$ifdef fpc} +{$mode objfpc} +{$endif fpc} + +{$APPTYPE CONSOLE} + +{$h+} + +uses + timer; + +function ComputePi(NumDigits: Integer): string; +var + A: array of LongInt; + I, J, K, P, Q, X, Nines, Predigit: Integer; + PiLength: Integer; +begin + start; + SetLength(A, 10*NumDigits div 3); + SetLength(Result, NumDigits+1); + PiLength := 1; + for I := Low(A) to High(A) do + A[I] := 2; + Nines := 0; + Predigit := 0; + for J := 0 to NumDigits-1 do + begin + Q := 0; + P := 2 * High(A) + 1; + for I := High(A) downto Low(A) do + begin + X := 10*A[I] + Q*(I+1); + A[I] := X mod P; + Q := X div P; + P := P - 2; + end; + A[Low(A)] := Q mod 10; + Q := Q div 10; + if Q = 9 then + Inc(Nines) + else if Q = 10 then + begin + Result[PiLength] := Chr(Predigit + 1 + Ord('0')); + for K := 1 to Nines do + Result[PiLength+K] := '0'; + PiLength := PiLength + Nines + 1; + Predigit := 0; + Nines := 0; + end + else + begin + Result[PiLength] := Chr(Predigit + Ord('0')); + Predigit := Q; + for K := 1 to Nines do + Result[PiLength+K] := '9'; + PiLength := PiLength + Nines + 1; + Nines := 0; + end; + end; + Result[PiLength] := Chr(Predigit + Ord('0')); + stop; +end; + +var + NumDigits: Integer; + Code: Integer; + F: TextFile; + result : string; +begin + if ParamCount = 0 then + WriteLn('usage: pi #DIGITS [FILE]') + else + begin + Val(ParamStr(1), NumDigits, Code); + if Code <> 0 then + begin + WriteLn('Invalid # digits: ', ParamStr(1)); + Halt(1); + end; + + if ParamCount > 1 then + begin + AssignFile(F, ParamStr(2)); + Rewrite(F); + WriteLn(F, ComputePi(NumDigits)); + CloseFile(F); + end + else + begin + result:=ComputePi(NumDigits); + WriteLn(result); + end; + end; +end.