MODULE C4P3;  (* Chapter 4  Problem 3 *)
	      (* Program RaisePower4 to accept negative integer value also *)
              (* RaisePower4: Raise x to y power using function procedure *)

  (* From the book "Modula-2  A Seafarer's Manual and Shipyard Guide" *)
  (* Page 121   adapted "Amiga M2Modula-2"   08 Mar 1988 *)

FROM InOut IMPORT WriteLn,
                  WriteString,
                  ReadInt;
FROM RealInOut IMPORT WriteReal,
                      ReadReal;
                      
VAR
  z,					(* receives result *)
  x : REAL;				(* base from keyboard *)
  y : INTEGER;				(* exponent from keyboard *)
  
PROCEDURE Getxy(VAR base : REAL;	(* get x & y from keyboard *)
                VAR exp : INTEGER);
  BEGIN
    WriteLn;
    WriteString ("Enter x: ");
    ReadReal (base);
    WriteLn;
    WriteString ("Enter y: ");
    ReadInt (exp);
  END Getxy;
  
PROCEDURE Power(t : REAL;		(* base *)
                e : INTEGER) : REAL;	(* exponent *)
  VAR
    xy : REAL;
    Positive : BOOLEAN;
  BEGIN
    Positive := (e >= 0);		(* Positive is TRUE when e >= 0 *)
    e := ABS (e);
    xy := 1.0;				(* initialize result *)
    WHILE (e # 0) DO
      WHILE (NOT ODD(e)) DO
        t := t * t;
        e := e DIV 2;
      END;   (* WHILE NOT *)
      xy := xy * t;
      DEC (e);
    END;   (* WHILE e *)
    IF NOT Positive THEN		(* calculate result for e < 0 *)
      xy := 1.0 / xy;
    END;
    RETURN xy;				(* return result *)
  END Power;
   
PROCEDURE DisplayAnswer(xtoy : REAL);
  BEGIN
    WriteLn;
    WriteString ("x to y power = ");
    WriteReal (xtoy,10,2);
    WriteLn;
  END DisplayAnswer;
 
BEGIN					(* MODULE RaisePower *)
  WriteLn;
  WriteString ("Calculating x to y power");
  Getxy(x,y);
  z := Power(x,y);
  DisplayAnswer(z);
   
END C4P3.
