packages feed

language-Modula2-0.1: examples/Modula-2_Libraries/andrea-m2/lib/multiscope/moremath.mod

IMPLEMENTATION MODULE MoreMath;

(* misc. extra math functions *)
(* new functions - J. Andrea, Aug.13/91 *)
(* J. Andrea, May.18/92 -dos version *)
(* J. Andrea, 1985 *)
(* This code may be freely used and distributed, it may not be sold. *)

FROM MathLib0 IMPORT sqrt, pow, ln;


    (* -------------------------------------------- *)
    PROCEDURE IModulus( a, b :INTEGER ) :INTEGER;
    (* return the integer modulus of two numbers
       handles a negative 'a' value (unlike the languages built in MOD) *)
    BEGIN

       IF a < 0 THEN
         RETURN b - (ABS(a) MOD b);
       ELSE
         RETURN a MOD b;
       END; (* if *)

    END IModulus;


    (* -------------------------------------------------- *)
    PROCEDURE CardPower( base, exponent :CARDINAL ) :CARDINAL;
    (* raise a cardinal to a cardinal power *)
    
    VAR
       x, i :CARDINAL;
       
    BEGIN

       IF exponent = 0 THEN
         x := 1;
       ELSE
       
         x := base;
         
         FOR i := 2 TO exponent DO
            x := x * base;
         END;
         
       END;

       RETURN x;
    END CardPower;


    (* -------------------------------------------------- *)
    PROCEDURE RealPower( base :REAL; exponent :CARDINAL ) :REAL;
    (* raise a real value to a cardinal power *)
    BEGIN

       RETURN pow( base, FLOAT( exponent ) );

    END RealPower;


    (* -------------------------------------------------- *)
    PROCEDURE IntPower( base, exponent :INTEGER ) :INTEGER;
    (* raise an integer to an integer power *)

    VAR
       x, i :INTEGER;
       
    BEGIN

       IF exponent = 0 THEN
         x := 1;
       ELSE
       
         IF exponent < 0 THEN
           x := 0;
         ELSE
         
           x := base;
         
           FOR i := 2 TO exponent DO
              x := x * base;
           END;
         END;
       END;

       RETURN x;
    END IntPower;


    (* -------------------------------------------------- *)
    PROCEDURE entier( a :REAL ) :INTEGER;
    (* return the nearest integer *)
    BEGIN

      IF ( a < -32768.0 ) OR ( a > 32767.0 ) THEN
	RETURN 0
      ELSE
        RETURN VAL( INTEGER, TRUNC( a ) )
      END;

    END entier;


    (* -------------------------------------------------- *)
    PROCEDURE Float( a :INTEGER ) :REAL;
    BEGIN
      RETURN real( a );
    END Float;


    (* -------------------------------------------------- *)
    PROCEDURE MinReal( a, b :REAL ) :REAL;
    BEGIN

       IF a < b THEN
         RETURN a;
       ELSE
         RETURN b;
       END;
       
    END MinReal;

    (* -------------------------------------------------- *)
    PROCEDURE MaxReal( a, b :REAL ) :REAL;
    BEGIN

       IF a > b THEN
         RETURN a;
       ELSE
         RETURN b;
       END;

    END MaxReal;


    (* -------------------------------------------------- *)
    PROCEDURE MinInt( a, b :INTEGER ) :INTEGER;
    BEGIN

       IF a < b THEN
         RETURN a;
       ELSE
         RETURN b;
       END;

    END MinInt;

    (* -------------------------------------------------- *)
    PROCEDURE MaxInt( a, b :INTEGER ) :INTEGER;
    BEGIN

       IF a > b THEN
         RETURN a;
       ELSE
         RETURN b;
       END;

    END MaxInt;


    (* -------------------------------------------------- *)
    PROCEDURE MinCard( a, b :CARDINAL ) :CARDINAL;
    BEGIN
    
       IF a < b THEN
         RETURN a;
       ELSE
         RETURN b;
       END;

    END MinCard;

    (* -------------------------------------------------- *)
    PROCEDURE MaxCard( a, b :CARDINAL ) :CARDINAL;
    BEGIN

       IF a > b THEN
         RETURN a;
       ELSE
         RETURN b;
       END;

    END MaxCard;


    (* -------------------------------------------------- *)
    PROCEDURE SizeCard( a :CARDINAL ) :CARDINAL;
    BEGIN

       IF a < 10 THEN
         RETURN 1;
       ELSE
         RETURN 1 + SizeCard( a DIV 10 );
       END;

    END SizeCard;

    (* -------------------------------------------------- *)
    PROCEDURE SizeInt( a :INTEGER ) :CARDINAL;
    BEGIN

       IF ABS( a ) < 10 THEN
         IF a < 0 THEN
           RETURN 2;
         ELSE
           RETURN 1;
         END;
       ELSE
         RETURN 1 + SizeInt( a DIV 10 );
       END;

    END SizeInt;


    (* -------------------------------------------------- *)
    PROCEDURE CalcPi() :REAL;

    CONST
      one  = 1.0;
      two  = 2.0;
      four = 4.0;
      six  = 6.0;
      
    VAR
      root_two, last, out, y, a, d, e :REAL;
      i                               :CARDINAL;

    BEGIN

      root_two := sqrt( two );

      last := 0.0;

      y := root_two - one;
      a := six - four * root_two;

      out := one / a;

      i := 0;
      WHILE out # last DO
        last := out;

        d := one - RealPower( y, 4 );
        d := sqrt( sqrt( d ) );

        y := ( one - d ) / ( one + d );

        i := i + 1;

        e := RealPower(two, 2*i+1) * y * ( one + y + y * y );
        a := RealPower(one+y, 4) * a - e;

        out := one / a;

      END;
      
      RETURN out;

    END CalcPi;

    (* -------------------------------------------- *)
    PROCEDURE Log10( x :REAL ) :REAL;
    BEGIN
      IF x <= 0.0 THEN
        RETURN 0.0;
      ELSE
        RETURN ln( x ) / ln( 10.0 );
      END;
    END Log10;
      (* -------------------------------------------- *)
    PROCEDURE Log2( x :REAL ) :REAL;
    BEGIN
      IF x <= 0.0 THEN
        RETURN 0.0;
      ELSE
        RETURN ln( x ) / ln( 2.0 );
      END;
    END Log2;
    
BEGIN
END MoreMath.