MODULE ObxPi;
(**
project = "BlackBox"
organization = "www.oberon.ch"
contributors = "Oberon microsystems"
version = "System/Rsrc/About"
copyright = "System/Rsrc/About"
license = "Docu/BB-License"
changes = ""
issues = ""
**)
IMPORT Int := Integers, StdLog;
PROCEDURE Pi* (digits: INTEGER): Int.Integer; (* entier(pi * 10^digits) *)
VAR p1, p2, inc, sum: Int.Integer; guard, div: INTEGER;
BEGIN
(* pi = 16 * atan(1/5) - 4 * atan(1/239) *)
(* atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... *)
guard := 8;
p1 := Int.Quotient(Int.Product(Int.Power(Int.Long(10), digits + guard), Int.Long(16)), Int.Long(5));
p2 := Int.Quotient(Int.Product(Int.Power(Int.Long(10), digits + guard), Int.Long(-4)), Int.Long(239));
sum := Int.Sum(p1, p2);
div := 1;
REPEAT
p1 := Int.Quotient(p1, Int.Long(-5 * 5));
p2 := Int.Quotient(p2, Int.Long(-239 * 239));
INC(div, 2);
inc := Int.Quotient(Int.Sum(p1, p2), Int.Long(div));
sum := Int.Sum(sum, inc)
UNTIL Int.Sign(inc) = 0;
RETURN Int.Quotient(sum, Int.Power(Int.Long(10), guard))
END Pi;
PROCEDURE WritePi* (digits: INTEGER);
VAR i: Int.Integer; s: ARRAY 10000 OF CHAR;
BEGIN
i := Pi(digits);
Int.ConvertToString(i, s);
StdLog.String(s); StdLog.Ln
END WritePi;
END ObxPi.