pidigits_example2.pas 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. { The Computer Language Benchmarks Game
  2. http://shootout.alioth.debian.org
  3. contributed by Vincent Snijders
  4. gmp headers by Karl-Michael Schindler
  5. }
  6. {$mode objfpc}
  7. program pidigits_example2;
  8. uses
  9. gmp;
  10. procedure PrintPiDigits(NumDigits: integer);
  11. var
  12. q, r, s, t: MPInteger; // Transformation matrix components.
  13. i, k, digit, c: integer;
  14. line: string[10];
  15. function Extract(x: cardinal): integer;
  16. begin
  17. result := (q * x + r) / (s * x + t);
  18. end;
  19. function IsSafe: boolean;
  20. begin
  21. result := digit = Extract(4);
  22. end;
  23. procedure Produce;
  24. begin
  25. r := 10 * (r - t * digit);
  26. q *= 10;
  27. end;
  28. procedure Consume;
  29. begin
  30. inc(k);
  31. r := r * (2 * k + 1) + q * (4 * k + 2);
  32. t := t * (2 * k + 1) + s * (4 * k + 2);
  33. s *= k;
  34. q *= k;
  35. end;
  36. begin
  37. k := 0;
  38. i := 0;
  39. c := 0;
  40. setlength(line, 10);
  41. q := 1;
  42. r := 0;
  43. s := 0;
  44. t := 1;
  45. while (i < NumDigits) do begin
  46. digit := Extract(3);
  47. while not IsSafe do begin
  48. Consume;
  49. digit := Extract(3);
  50. end;
  51. Produce;
  52. inc(c);
  53. line[c] := chr(ord('0') + digit);
  54. inc(i);
  55. if c = 10 then begin
  56. writeln(line, #9':', i);
  57. c := 0;
  58. end;
  59. end;
  60. if c <> 0 then begin
  61. SetLength(line, c);
  62. writeln(line);
  63. end;
  64. end;
  65. var
  66. n: integer = 27;
  67. begin
  68. if (ParamCount = 1) then
  69. val(ParamStr(1), n);
  70. PrintPiDigits(n);
  71. end.