MODULE ObxPi;
(**
	project	= "BlackBox"
	organization	= "www.oberon.ch"
	contributors	= "Oberon microsystems"
	version	= "System/Rsrc/About"
	copyright	= "System/Rsrc/About"
	license	= "Docu/BB-License"
	changes	= "
	- YYYYMMDD, nn, ...
	"
	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.
