2
0

pidigits_example.pas 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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_example;
  8. uses
  9. gmp;
  10. procedure PrintPiDigits(NumDigits: integer);
  11. var
  12. q, r, s, t: mpz_t; // Transformation matrix components.
  13. u, v, w: mpz_t; // Temporary variables
  14. i, k, digit, c: integer;
  15. line: string[10];
  16. function Extract(x:cardinal): integer;
  17. begin
  18. mpz_mul_ui(u, q, x);
  19. mpz_add(u, u, r);
  20. mpz_mul_ui(v, s, x);
  21. mpz_add(v, v, t);
  22. mpz_tdiv_q(w, u, v);
  23. result := mpz_get_ui(w);
  24. end;
  25. function IsSafe: boolean;
  26. begin
  27. result := digit = Extract(4);
  28. end;
  29. procedure Produce;
  30. begin
  31. mpz_mul_si(r, r, 10);
  32. mpz_mul_si(v, t, -10 * digit);
  33. mpz_add(r, r, v);
  34. mpz_mul_si(q, q, 10);
  35. end;
  36. procedure Consume;
  37. begin
  38. inc(k);
  39. mpz_mul_si(r, r, 2*k+1);
  40. mpz_mul_si(u, q, 4*k+2);
  41. mpz_add(r, r, u);
  42. mpz_mul_si(t, t, 2*k+1);
  43. mpz_mul_si(v, s, 4*k+2);
  44. mpz_add(t, t, v);
  45. mpz_mul_si(s, s, k);
  46. mpz_mul_si(q, q, k);
  47. end;
  48. begin
  49. k := 0;
  50. i := 0;
  51. c := 0;
  52. setlength(line, 10);
  53. mpz_init_set_ui(q, 1);
  54. mpz_init_set_ui(r, 0);
  55. mpz_init_set_ui(s, 0);
  56. mpz_init_set_ui(t, 1);
  57. mpz_init(u);
  58. mpz_init(v);
  59. mpz_init(w);
  60. while (i < NumDigits) do begin
  61. digit := Extract(3);
  62. while not IsSafe do begin
  63. Consume;
  64. digit:= Extract(3);
  65. end;
  66. Produce;
  67. inc(c);
  68. line[c] := chr(ord('0') + digit);
  69. inc(i);
  70. if c = 10 then begin
  71. writeln(line, #9':', i);
  72. c := 0;
  73. end;
  74. end;
  75. if c <> 0 then begin
  76. SetLength(line, c);
  77. writeln(line);
  78. end;
  79. mpz_clear(q);
  80. mpz_clear(r);
  81. mpz_clear(s);
  82. mpz_clear(t);
  83. mpz_clear(u);
  84. mpz_clear(v);
  85. mpz_clear(w);
  86. end;
  87. var
  88. n: integer = 27;
  89. begin
  90. if (ParamCount = 1) then
  91. val(ParamStr(1), n);
  92. PrintPiDigits(n);
  93. end.