pi.pp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. program pi;
  2. {$ifdef fpc}
  3. {$mode objfpc}
  4. {$endif fpc}
  5. {$APPTYPE CONSOLE}
  6. {$implicitexceptions off}
  7. {$h+}
  8. uses
  9. timer;
  10. type
  11. tchararray = array of char;
  12. function ComputePi(NumDigits: Integer): tchararray;
  13. var
  14. A: array of LongInt;
  15. I, J, K, P, Q, X, Nines, Predigit: Integer;
  16. PiLength, ArrHigh: Integer;
  17. begin
  18. start;
  19. SetLength(A, 10*NumDigits div 3);
  20. SetLength(Result, NumDigits+1);
  21. PiLength := 0;
  22. ArrHigh:=high(A);
  23. for I := Low(A) to ArrHigh do
  24. A[I] := 2;
  25. Nines := 0;
  26. Predigit := 0;
  27. for J := 0 to NumDigits-1 do
  28. begin
  29. Q := 0;
  30. P := 2 * ArrHigh + 1;
  31. for I := ArrHigh downto Low(A) do
  32. begin
  33. X := 10*A[I] + Q*(I+1);
  34. A[I] := X mod P;
  35. Q := X div P;
  36. P := P - 2;
  37. end;
  38. A[Low(A)] := Q mod 10;
  39. Q := Q div 10;
  40. if Q = 9 then
  41. Inc(Nines)
  42. else if Q = 10 then
  43. begin
  44. Result[PiLength] := Chr(Predigit + 1 + Ord('0'));
  45. for K := 1 to Nines do
  46. Result[PiLength+K] := '0';
  47. PiLength := PiLength + Nines + 1;
  48. Predigit := 0;
  49. Nines := 0;
  50. end
  51. else
  52. begin
  53. Result[PiLength] := Chr(Predigit + Ord('0'));
  54. Predigit := Q;
  55. for K := 1 to Nines do
  56. Result[PiLength+K] := '9';
  57. PiLength := PiLength + Nines + 1;
  58. Nines := 0;
  59. end;
  60. end;
  61. Result[PiLength] := Chr(Predigit + Ord('0'));
  62. stop;
  63. end;
  64. var
  65. NumDigits: Integer;
  66. Code: Integer;
  67. F: TextFile;
  68. arrayresult: tchararray;
  69. result : string;
  70. begin
  71. if ParamCount = 0 then
  72. WriteLn('usage: pi #DIGITS [FILE]')
  73. else
  74. begin
  75. Val(ParamStr(1), NumDigits, Code);
  76. if Code <> 0 then
  77. begin
  78. WriteLn('Invalid # digits: ', ParamStr(1));
  79. Halt(1);
  80. end;
  81. arrayresult:=ComputePi(NumDigits);
  82. setlength(result,NumDigits+1);
  83. move(arrayresult[0],result[1],(NumDigits+1)*sizeof(result[1]));
  84. if ParamCount > 1 then
  85. begin
  86. AssignFile(F, ParamStr(2));
  87. Rewrite(F);
  88. WriteLn(F, result);
  89. CloseFile(F);
  90. end
  91. else
  92. begin
  93. WriteLn(result);
  94. end;
  95. end;
  96. end.