Go to the first, previous, next, last section, table of contents.


Mathematics

The mathematics modules described in this chapter serve several purposes. They provide access to the underlying representation of REAL and LONGREAL values, as well as facilities for common mathematical functions and constants.

The REAL and LONGREAL types, collectively referred to as the real numeric types, are used to represent floating-point numbers, which may be stored in various ways on a computer. The actual values are approximations of real numbers and may not be wholely accurate. Hence, precise details of the floating-point representation are often required when creating operations that involve real numeric types in order to minimize errors and calculate error bounds.

A full discourse on floating-point numbers, as well as more complete descriptions of algorithms used for manipulating floating-point data, is beyond the scope of this manual. For further information, consult the following references:

IEEE Standard for Binary Floating-Point Arithmetic
(ANSI/IEEE STD 754-1985) (R1990) 
Institute of Electrical and Electronics Engineers, Inc. (IEEE)

IEEE Standard for Radix-Independent Floating-Point Arithmetic
(ANSI/IEEE STD 854-1987) (R1994)
Institute of Electrical and Electronics Engineers, Inc. (IEEE)

Information technology -- Language independent arithmetic -- 
Part 1: Integer and floating point arithmetic
(ISO/IEC 10967-1:1994(E))
International Organization for Standardization (ISO)

What Every Computer Scientist Should Know About Floating-Point Arithmetic
David Goldberg
ACM Computing Surveys, Vol. 23, No. 1, March 1991, pp. 5-48

Software Manual for the Elementary Functions
William James Cody
Prentice Hall, July 1980

Computer Approximations
John F. Hart
Krieger Publishing Company, June 1978

Low-level Numeric Properties

The modules LowReal and LowLReal give access to the underlying properties of the types REAL and LONGREAL.

Default properties of the real numeric types are defined by the constants in these modules. (An implementation may provide facilities for dynamically changing properties from these defaults.)

Please note:

Constant: radix
The whole number value of the radix (base number system) used to represent the corresponding real number values. (Most modern computers use IEEE 754, which defines the radix to be 2.)

Constant: places
A whole number value representing of the number of radix places used to store values of the corresponding real numeric type.

Constant: expoMax
A whole number value representing the largest possible exponent of the corresponding real numeric type.

Constant: expoMin
A whole number value representing the smallest possible exponent of the corresponding real numeric type.

Please note: It is possible that expoMin = expoMax, which is likely for the case of fixed point representation.

Constant: large
The largest possible value of the corresponding real numeric type.

Please note: On some systems, large may be a machine representation of infinity.

Constant: small
The smallest possible positive value of the corresponding real numeric type, represented to maximal precision.

Please note: If an implementation has stored values strictly between `0.0' and small, then presumbly the implementation supports gradual underflow.

Constant: IEC559
A boolean value that is TRUE if, and only if, the implementation of the corresponding real numeric type conforms to IEC 559:1989 (IEEE 754:1987) in all regards.

Please note:

Constant: LIA1
A boolean value that is TRUE if, and only if, the implementation of the corresponding real numeric type conforms to ISO/IEC 10967-1:199x (LIA-1) in all regards: parameters, arithmetic, exceptions, and notification.

Constant: rounds
A boolean value that is TRUE if, and only if, each operation produces a result that is one of the values of the corresponding real numeric type nearest to the mathematical result.

Please note: If rounds is TRUE, and the mathematical result lies mid-way between two values of the corresponding real numeric type, then the selection from the two possible values is implementation-dependent.

Constant: gUnderflow
A boolean value that is TRUE if, and only if, there are values of the corresponding real numeric type between `0.0' and small.

Constant: exception
A boolean value that is TRUE if, and only if, every operation that attempts to produce a real value out of range raises an exception.

Constant: extend
A boolean value that is TRUE if, and only if, expressions of the corresponding real numeric type are computed to higher precision than the stored values.

Please note: If extend is TRUE, then values greater than large can be computed in expressions, but cannot be stored in variables.

Constant: nModes
A whole number value giving the number of bit positions needed for the status flags for mode control.

Data type: Modes = SET
This type is used to represent the status flags that apply to the underlying implementation of the corresponding real numeric type. This type is used for the setMode and currentMode() procedures.

The following functions are provided in either LowReal (for REAL) or LowLReal (for LONGREAL):

Function: exponent (x: REAL): INTEGER
Function: exponent (x: LONGREAL): INTEGER
This function returns the exponent value of x, which must lie between expoMin and expoMax. If x=0.0, an exception occurs and may be raised.

Function: fraction (x: REAL): REAL
Function: fraction (x: LONGREAL): LONGREAL
This function returns the significand (or significant) part of x. Hence, the following relationship holds:
x = scale(fraction(x), exponent(x))

Function: IsInfinity (real: REAL): BOOLEAN
Function: IsInfinity (real: LONGREAL): BOOLEAN
This function returns TRUE if, and only if, real is a representation of Infinity (either positive or negative).

Function: IsNaN (real: REAL): BOOLEAN
Function: IsNaN (real: LONGREAL): BOOLEAN
This function returns TRUE if, and only if, real is a NaN ("Not a Number") representation.

Please note: The routines IsInfinity and IsNaN allow, for example, for string formatting routines to have a reasonably portable way to check whether they are dealing with out of range or illegal numbers.

Function: sign (x: REAL): REAL
Function: sign (x: LONGREAL): LONGREAL
This function returns the sign of x as follows:
  If x > 0.0, return 1.0
  If x = 0.0, return either 1.0 or -1.0
  If x < 0.0, return -1.0

Please note: The uncertainty about the handling of 0.0 is to allow for systems that distinguish between +0.0 and -0.0 (such as IEEE 754 systems).

Function: succ (x: REAL): REAL
Function: succ (x: LONGREAL): LONGREAL
This function returns the next value of the corresponding real numeric type greater than x, if such a value exists; otherwise, an exception occurs and may be raised.

Function: ulp (x: REAL): REAL
Function: ulp (x: LONGREAL): LONGREAL
This function returns the value of the corresponding real numeric type equal to a unit in the last place of x, if such a value exists; otherwise, an exception occurs and may be raised.

Please note: When this value exists, one, or both, of the following is true: ulp(x) = succ(x)-x or ulp(x) = x-pred(x).

Function: pred (x: REAL): REAL
Function: pred (x: LONGREAL): LONGREAL
This function returns the next value of the corresponding real numeric type less than x, if such a value exists; otherwise, an exception occurs and may be raised.

Function: intpart (x: REAL): REAL
Function: intpart (x: LONGREAL): LONGREAL
This function returns the integral part of x. For negative values, this is -intpart(abs(x)).

Function: fractpart (x: REAL): REAL
Function: fractpart (x: LONGREAL): LONGREAL
This function returns the fractional part of x. This satisfies the relationship fractpart(x) + intpart(x) = x.
Function: scale (x: REAL; n: INTEGER): REAL
Function: scale (x: LONGREAL; n: INTEGER): LONGREAL
This function returns x*radix^n, if such a value exists; otherwise, an exception occurs and may be raised.

Function: trunc (x: REAL; n: INTEGER): REAL
Function: trunc (x: LONGREAL; n: INTEGER): LONGREAL
This function returns the value of the most significant n places of x. If n is less than or equal to zero, an exception occurs and may be raised.

Function: round (x: REAL; n: INTEGER): REAL
Function: round (x: LONGREAL; n: INTEGER): LONGREAL
This function returns the value of x rounded to the most significant n places. If such a value does not exist, or if n is less than or equal to zero, an exception occurs and may be raised.

Function: synthesize (expart: INTEGER; frapart: REAL): REAL
Function: synthesize (expart: INTEGER; frapart: LONGREAL): LONGREAL
This function returns a value of the corresponding real numeric type contructed from the value of expart and frapart. This value satisfies the relationship
synthesize(exponent(x), fraction(x)) = x.

Procedure: setMode (m: Modes)
This procedure sets status flags from the value of m, appropriate to the underlying implementation of the corresponding real numeric type.

Please note:

Function: currentMode (): Modes
This function returns the current status flags (in the form set by setMode), or the default status flags (if setMode is not used).

Please note: The returned value is not necessarily the value set by setMode, because a call of setMode might attempt to set flags that cannot be set by the program.

Function: IsLowException (): BOOLEAN
This function returns TRUE if the current process is in the exceptional execution state because of the raising of the corresponding LowReal or LowLReal exception; otherwise, it returns FALSE.

Mathematical Functions

The modules RealMath and LRealMath provide facilities for common mathematical functions and constants for REAL and LONGREAL numeric types.

Please note: The angle in all trigonometric functions is measured in radians.

The following useful mathematical constants are provided:

Constant: pi
An implementation-defined approximation to the mathematical constant pi.

Constant: exp1
An implementation-defined approximation to the mathematical constant e.

Please note: Due to the approximations involved, sin(pi) might not exactly equal zero. Similarly, exp1 might not exactly equal exp(1).

The following are mathematical functions provided in either RealMath (for REAL) or LRealMath (for LONGREAL):

Function: sqrt (x: REAL): REAL
Function: sqrt (x: LONGREAL): LONGREAL
This function returns an approximation to the positive square root of x. If x is negative, an exception is raised.

Function: exp (x: REAL): REAL
Function: exp (x: LONGREAL): LONGREAL
This function returns an approximation to the mathematical constant e raised to the power of x.

Function: ln (x: REAL): REAL
Function: ln (x: LONGREAL): LONGREAL
This function returns an approximation to the natural logarithm of x. If x is zero or negative, an exception is raised.

Function: sin (x: REAL): REAL
Function: sin (x: LONGREAL): LONGREAL
This function returns an approximation to the sine of x for all values of x.
Function: cos (x: REAL): REAL
Function: cos (x: LONGREAL): LONGREAL
This function returns an approximation to the cosine of x for all values of x.
Function: tan (x: REAL): REAL
Function: tan (x: LONGREAL): LONGREAL
This function returns an approximation to the tangent of x. If x is an odd multiple of pi/2, an exception is raised.

Function: arcsin (x: REAL): REAL
Function: arcsin (x: LONGREAL): LONGREAL
This function returns an approximation to the arcsine of x. The result will be in the range [-pi/2, pi/2]. If the absolute value of x is greater than one, an exception is raised.
Function: arccos (x: REAL): REAL
Function: arccos (x: LONGREAL): LONGREAL
This function returns an approximation to the arccosine of x. The result will be in the range [0, pi]. If the absolute value of x is greater than one, an exception is raised.

Function: arctan (x: REAL): REAL
Function: arctan (x: LONGREAL): LONGREAL
This function returns an approximation to the arctangent of x for all values of x. The result will be in the range [-pi/2, pi/2].
Function: power (base, exponent: REAL): REAL
Function: power (base, exponent: LONGREAL): LONGREAL
This function returns an approximation to the value of base raised to the power exponent. If base is zero or negative, an exception is raised.

Please note: This function is mathematically equivalent to
exp(exponent * ln(base)), but may be computed differently.

Function: round (x: REAL): LONGINT
Function: round (x: LONGREAL): LONGINT
This function returns the nearest integer to the value of x. If the mathematical result is not within the range of the type LONGINT, an exception occurs and may be raised.

Please note: If the value of x is midway between two integer values, the result is an implementation-defined selection of one of the two possible values.

Function: IsRMathException (): BOOLEAN
This function returns TRUE if the current process is in the exceptional execution state because of the raising of the corresponding RealMath or LRealMath exception; otherwise, it returns FALSE.

Arbitrary Precision Integers

Very often, a program requires numbers with a greater range or accuracy than exists with the built-in Oberon-2 integer types. Hence, the module `Integers' provides facilities for arbitrary precision integer operations.

For further information on how these kinds of facilites may be implemented, consult the following reference:

The Art Of Computer Programming:
Volume 2, Seminumerical Algorithms, Second Edition
Donald E. Knuth
Addison-Wesley Publishing Co., January 1981

Data type: Integer = POINTER TO IntegerDesc
Instances of this type are used to represent arbitrary precision integers.

The following operations are used to create initial instances of Integer and convert Integers to standard numeric types.

Function: Entier (x: LONGREAL): Integer
This function returns an instance of Integer whose value is the largest integer not greater than x.

Example:

VAR n: Integers.Integer;

n:=Integers.Entier(1.0D20); 
   => n = 100000000000000000000

n:=Integers.Entier(1111111111.5D0); 
   => n = 1111111111

n:=Integers.Entier(0.0); 
   => n = 0

Function: Float (x: Integer): LONGREAL
This function returns an approximation to the value of x converted to a LONGREAL. If the result cannot be represented as a LONGREAL because the value of x is either too large or too small, this function returns either MIN(LONGREAL) or MAX(LONGREAL).
Function: Long (x: LONGINT): Integer
This function returns an instance of Integer whose value is x.
Function: Short (x: Integer): LONGINT
This function returns the value of x converted to a LONGINT. If the result cannot be represented as a LONGINT because the value of x is either too large or too small, this function returns either MIN(LONGINT) or MAX(LONGINT).

Example:

VAR n: Integers.Integer;
    s: LONGINT;
    f: LONGREAL; 

n:=Integers.Long(1234);
s:=Integers.Short(n); 
   => s = 1234
f:=Integers.Float(n);
   => f = 1.23400000000000E+3

n:=Integers.Long(80000000H); 
s:=Integers.Short(n); 
   => s = -2147483648
f:=Integers.Float(n);
   => f = -2.14748364800000E+9

n:=Integers.Long(7FFFFFFFH);
s:=Integers.Short(n); 
   => s = 2147483647
f:=Integers.Float(n);
   => f = 2.14748364700000E+9

The following are common mathematical operations, which operate on Integers:

Function: Abs (x: Integer): Integer
This function returns the absolute value of x.

Function: Odd (x: Integer): BOOLEAN
This function returns TRUE if x is an odd number, and FALSE if it is even.

Function: Compare (x, y: Integer): LONGINT
This function compares the values of x and y and gives the following result:
  If x > y, return 1
  If x = y, return 0
  If x < y, return -1

Function: Difference (x, y: Integer): Integer
This function returns the difference of x and y (i.e., x-y).

Example:

VAR n: Integers.Integer;

n:=Integers.Difference(Integers.Long(2000000), Integers.Long(999));
   => n = 1999001

n:=Integers.Difference(Integers.Long(999), Integers.Long(-2000000)); 
   => n = -2000999

n:=Integers.Difference(Integers.Long(-999), Integers.Long(999)); 
   => n = -1998

n:=Integers.Difference(Integers.Long(-2000000), Integers.Long(-999)); 
   => n = -1999001

Function: Sum (x, y: Integer): Integer
This function returns the sum of x and y (i.e., x+y).

Example:

VAR n: Integers.Integer;

n:=Integers.Sum(Integers.Long(999), Integers.Long(2000000));
   => n = 2000999

n:=Integers.Sum(Integers.Long(999), Integers.Long(-2000000)); 
   => n = -1999001

n:=Integers.Sum(Integers.Long(-999), Integers.Long(999)); 
   => n = 0

n:=Integers.Sum(Integers.Long(-2000000), Integers.Long(-999)); 
   => n = -2000999

Function: Product (x, y: Integer): Integer
This function returns the product of x and y (i.e., x*y).

Example:

VAR n: Integers.Integer;

n:=Integers.Product(Integers.Long(100000000), Integers.Long(100000000)); 
   => n = 10000000000000000

n:=Integers.Product(Integers.Long(71234), Integers.Long(66000)); 
   => n = 4701444000

Function: Quotient (x, y: Integer): Integer
This function returns the quotient of x divided by y (i.e., x DIV y).

Pre-condition: y is not zero.

Function: Remainder (x, y: Integer): Integer
This function returns the remainder of x divided by y (i.e., x MOD y).

Pre-condition: y is not zero.

Example:

VAR m, n: Integers.Integer;

n:=Integers.Quotient(Integers.Long(2000000000), Integers.Long(1234)); 
m:=Integers.Remainder(Integers.Long(2000000000), Integers.Long(1234)); 
   => n = 1620745, m = 670

n:=Integers.Quotient(Integers.Long(2000000000), Integers.Long(123456)); 
m:=Integers.Remainder(Integers.Long(2000000000), Integers.Long(123456)); 
   => n = 16200, m = 12800

Procedure: QuoRem (x, y: Integer; VAR quo, rem: Integer)
This procedure calculates both the quotient and remainder of x divided by y.

Pre-condition: y is not zero.

Example:

VAR m, n: Integers.Integer;

Integers.QuoRem(Integers.Long(2000000000), Integers.Long(1234), n, m); 
   => n = 1620745, m = 670

Integers.QuoRem(Integers.Long(2000000000), Integers.Long(123456), n, m); 
   => n = 16200, m = 12800

Function: GCD (x, y: Integer): Integer
This function returns the greatest common divisor of x and y.

Example:

VAR n: Integers.Integer; 

n:=Integers.GCD(Integers.Long(40902), Integers.Long(24140));
   => n = 34

n:=Integers.GCD(Integers.Long(27182818), Integers.Long(10000000));
   => n = 2

n:=Integers.GCD(Integers.Long(2940), Integers.Long(238));
   => n = 14

Function: Power (x: Integer; exp: LONGINT): Integer
This function returns the value of x raised to the power exp.

Pre-condition: exp is greater than zero.

Example:

VAR n: Integers.Integer; 

n:=Integers.Power(Integers.Long(2940), 2);
   => n = 8643600

n:=Integers.Power(Integers.Long(2), 33);
   => n = 8589934592

n:=Integers.Power(Integers.Long(10), 9);
   => n = 1000000000

n:=Integers.Power(Integers.Long(2), 100);
   => n = 1267650600228229401496703205376

Function: Sign (x: Integer): SHORTINT
This function returns the sign of x as follows:
  If x > 0, return 1
  If x = 0, return 0
  If x < 0, return -1

Function: Factorial (x: LONGINT): Integer
This function returns x factorial (i.e., x!=x(x-1)(x-2)...(2)(1)).

Pre-condition: x is not negative.

Example:
VAR n: Integers.Integer; 

n:=Integers.Factorial(13);
   => n = 6227020800

n:=Integers.Factorial(20);
   => n = 2432902008176640000

The following operations are used to extract pieces of Integers:

Function: ThisDigit10 (x: Integer; exp10: LONGINT): CHAR
This function returns a single character, which represents the digit in x located at position exp10. Note that the right most digit (i.e., the "ones" place) has position zero.

Pre-condition: exp10 is not negative.

Example:
VAR n: Integers.Integer; 
    c: CHAR;

Integers.ConvertFromString("1267650600228229401496703205376", n);

c:=Integers.ThisDigit10(n, 0);
   => c = "6"

c:=Integers.ThisDigit10(n, 10);
   => c = "9"

c:=Integers.ThisDigit10(n, 30);
   => c = "1"

Function: Digits10Of (x: Integer): LONGINT
This function returns the value of the last ten digits of x (i.e., it returns x MOD 1000000000).

Example:

VAR n: Integers.Integer; 
    s: LONGINT;

Integers.ConvertFromString("1267650600228229401496703205376", n);

s:=Integers.Digits10Of(n);
   => s = 703205376

The following operations are used to convert between strings and Integers:

Procedure: ConvertFromString (s: ARRAY OF CHAR; VAR x: Integer)
This procedure converts s to an Integer value, which is assigned to x. Leading spaces and tab characters in s are skipped.

Pre-condition: s is in the form of a signed whole number (see section Syntax of Text Tokens)

Procedure: ConvertToString (x: Integer; VAR s: ARRAY OF CHAR)
This procedure converts x to a string value, which is assigned to s.

Example:

VAR n: Integers.Integer; 
    str: ARRAY 1024 OF CHAR;

Integers.ConvertFromString("1234567890", n);
   => n = 1234567890
Integers.ConvertToString(n, str); 
   => str = "1234567890"

Integers.ConvertFromString("  -9999999999", n); 
   => n = -9999999999
Integers.ConvertToString(n, str);
   => str = "-9999999999"

Integers.ConvertFromString(" 12345678901234567890123456789", n);
   => n = 12345678901234567890123456789
Integers.ConvertToString(n, str); 
   => str = "12345678901234567890123456789"

The following operations can be used to internalize and externalize Integers (i.e., read from and write to channels):

Procedure: Externalize (VAR w: BinaryRider.Writer; x: Integer)
Writes the value of x to a channel using writer w.
Procedure: Internalize (VAR r: BinaryRider.Reader; VAR x: Integer)
Retrieves a stored Integer value from a channel using reader r, and assigns it to x.

Arbitrary Precision Real Numbers

Module `Reals' provides facilities for arbitrary precision floating point operations. Real numbers are represented by type Real. These facilities are based on a FORTRAN library (MPFUN) created by David H. Bailey. For more information, see

http://www.nersc.gov/~dhb/

or contact mp-request@nas.nasa.gov.

Numeric Precision-setting Constants

Constant: maxDigits
Initial precision level in digits.

Constant: outDigits
Initial output precision level in digits.

Constant: log10eps
The initial multiprecision "epsilon" level.

Constant: maxMant
Maximum mantissa precision in (machine) words.

Constant: maxExp
Maximum exponent precision.

Types

Data type: Real = POINTER TO RealDesc
Instances of this type are used to represent arbitrary precision floating point numbers.

Variables

Variable: err: INTEGER

Read-only Variable: curMant: INTEGER
Current mantissa precision in (machine) words.

Read-only Variable: sigDigs: INTEGER

Read-only Variable: eps: Real
Current multiprecision "epsilon" level.

Read-only Variable: ln2: Real
An approximation of the value of the natural logarithm of `2'.

Read-only Variable: pi: Real
An approximation of the mathematical constant pi.

Read-only Variable: ln10: Real
An approximation of the value of the natural logarithm of `10'.

Procedures

The following operations are used to create initial instances of Real and convert Reals to standard numeric types.

Function: Long (x: LONGREAL): Real
This function returns an instance of Real whose value is x.

Function: Copy (a: Real): Real
This function returns a new instance of Real that has the same value as a.

The following operations are used to convert between strings and Reals:

Function: ToReal (str: ARRAY OF CHAR): Real
This procedure converts str to a Real value and returns the result.

The numeric representation of str must be of the format

number = ["+" | "-"] {decimal_digit} ["." {decimal_digit}] [scale]

where  scale = ("E" | "D") ["+" | "-"] decimal_digit 
               {decimal_digit}
and    decimal_digit = "0".."9" | " "

Thus the following is a valid input:

"1.23456 12938 23456 E + 200"

Please note: This real number definition is backwardly compatible with the Oberon-2 real string, but it has been extended to allow splitting of very large numbers into more readable segments by inserting spaces.

Procedure: ToString (a: Real; VAR str: ARRAY OF CHAR; n: LONGINT)
This procedure converts a to a string value in scientific notation with n significant places. The result it assigned to str. Note that the length of str should be at least `n+15' characters.

Function: short (q: Real): LONGREAL
This function returns the value of q converted to a LONGREAL value. If the result cannot be represented as a LONGREAL because the value of q is either too large or too small, this function returns either MIN(LONGREAL) or MAX(LONGREAL).

Function: entier (q: Real): Real
This function returns an instance of Real whose value is the largest integer not greater than q.

Example:

VAR n: Reals.Real;

n:=entier(Reals.Long(3.6));  (* ENTIER(3.6) *)
   => n = 3.0E+0

n:=entier(Reals.Long(-3.6));  (* ENTIER(-3.6) *)
   => n = -4.0E+0

Function: fraction (q: Real): Real
This function returns the fractional part of q.

Function: add (z1, z2: Real): Real
This function returns the sum of z1 and z2 (i.e., z1+z2).

Function: sub (z1, z2: Real): Real
This function returns the difference of z1 and z2 (i.e., z1-z2).

Function: mul (z1, z2: Real): Real
This function returns the product of z1 and z2 (i.e., z1*z2).

Function: div (z1, z2: Real): Real
This function returns the quotient of z1 divided by z2 (i.e., z1/z2).

Pre-condition: z2 is not zero.

Example:

VAR m, n, s: Reals.Real;

m:=Reals.ToReal("0.123456789012345678901234567890123456790");
   => m = 1.234567890123456789012345678E-1

n:=Reals.ToReal("123456789012345678901234567890123456789");
   => n = 1.234567890123456789012345678E+38

s:=Reals.add(n, m);
   => s = 1.234567890123456789012345678E+38

s:=Reals.sub(n, m);
   => s = 1.234567890123456789012345678E+38

s:=Reals.div(n, m);
   => s = 1.0E+39

s:=Reals.mul(n, m);
   => s = 1.524157875323883675049535156E+37

s:=Reals.div(Reals.Long(1), Reals.Long(3));  (* 1/3 *)
   => s = 3.333333333333333333333333333E-1

n:=Reals.add(s, s);  (* 1/3+1/3 *)
   => n = 6.666666666666666666666666666E-1

s:=Reals.div(Reals.Long(1), Reals.Long(3));  (* 1/3 *)
   => s = 3.333333333333333333333333333E-1

n:=Reals.mul(s, s);  (* 1/3*1/3 *) 
   => n =1.111111111111111111111111111E-1

s:=Reals.div(Reals.Long(1), Reals.Long(3));  (* 1/3 *)
   => s = 3.333333333333333333333333333E-1

n:=Reals.mul(s, Reals.Long(3));  (* 1/3*3 *)
   => n = 1.0E+0

Function: abs (z: Real): Real
This function returns the absolute value of z.

Function: cmp (a, b: Real): LONGINT
This function compares the values of a and b and gives the following result:
  If a > b, return 1
  If a = b, return 0
  If a < b, return -1

Note that this operation is faster than merely subtracting a and b and examining the sign of the result.

Function: power (x, exp: Real): Real
This function returns the value of x raised to the power exp.

Pre-condition: exp is greater than zero.

Example:

VAR n: Reals.Real;

n:=Reals.power(Reals.Long(2.0), Reals.Long(64));  (* 2^64 *)
   => n = 1.8446744073709551616E+19

Function: root (z: Real; n: LONGINT): Real
This function returns the value of the nth root of z.

Pre-condition: z is non-negative.

Example:

VAR n: Reals.Real;

n:=Reals.root(Reals.Long(-8), 3);  (* -8^(-1/3) *)
   => n = -2.0E+0

n:=Reals.root(Reals.power(Reals.Long(2), Reals.Long(64)), 64);
   => n = 2.0E+0    (* (2^64)^(-1/64) *)

Function: sqrt (z: Real): Real
This function returns the principal square root of z. The value of the result is in the range [-pi/2, pi/2].

Pre-condition: x is non-negative.

Function: exp (z: Real): Real
This function returns the complex exponential of z (the mathematical constant e raised to the power of z).

Function: ln (z: Real): Real
This function returns the principal value of the natural logarithm of z.

Pre-condition: z is positive.

Function: log (z, base: Real): Real
This function returns the principal value of the base base logarithm of z.

Pre-condition: z is positive.

Example:

VAR n: Reals.Real;

n:=Reals.log(Reals.eps, Reals.Long(10));  (* log10(eps) *)
   => n = -4.9E+2

Function: sin (z: Real): Real
This function returns the sine of z.

Function: cos (z: Real): Real
This function returns the cosine of z.

Procedure: sincos (z: Real; VAR sin, cos: Real)
This function returns both the sine and cosine of z.

Example:

VAR m, n: Reals.Real;

Reals.sincos(pi, m, n);
   => m = 0.0E+0  (* Sin(pi) *)
   => n =-1.0E+0  (* Cos(pi) *)

Reals.sincos(div(pi, Reals.Long(8)), m, n);  
   => m = 3.82683432365089771728459984E-1   (* Sin(pi/8) *)
   => n = 9.238795325112867561281831893E-1  (* Cos(pi/8) *)

Reals.sincos(Reals.Long(1), m, n);
   => m = 8.414709848078965066525023216E-1  (* Sin(1) *)
   => n = 5.403023058681397174009366074E-1  (* Cos(1) *)

Function: tan (z: Real): Real
This function returns tangent of z.

Pre-condition: z is not an odd multiple of pi/2.

Function: arcsin (z: Real): Real
This function returns the arcsine of z. The result is in the range [-pi/2, pi/2].

Pre-condition: the absolute value of z is less than or equal to one.

Example:

VAR n: Reals.Real;

n:=Reals.arcsin(Reals.sin(Reals.Long(1)));  (* arcsin(sin(1)) *)
   => n = 1.0E+0

Function: arccos (z: Real): Real
This function returns the arccosine of z. The result is in the range [0, pi].

Pre-condition: the absolute value of z is less than or equal to one.

Function: arctan (z: Real): Real
This function returns the arctangent of z. The result is in the range [-pi/2, pi/2].

Example:

VAR n: Reals.Real;

n:=Reals.mul(Reals.Long(4), Reals.arctan(Reals.Long(1)));
   (* 4*arctan(1) *)
   => n = 3.141592653589793238462643383E+0

Function: arctan2 (xn, xd: Real): Real
This function returns the arctangent of xn/xd. The signs of the two arguments are taken into account when determining quadrant information. The result is in the range [-pi, pi].

Procedure: sinhcosh (z: Real; VAR sinh, cosh: Real)
This function returns both the hyberbolic sine and cosine of z.

Function: sinh (z: Real): Real
This function returns the hyperbolic sine of z.

Function: cosh (z: Real): Real
This function returns the hyperbolic cosine of z.

Function: tanh (z: Real): Real
This function returns the hyperbolic tangent of z.

Procedure: SetWords (words: INTEGER)
This procedure sets the value of the current mantissa precision in (machine) words (i.e., sets the value of curMant).

Complex Numbers

The modules ComplexMath and LComplexMath provide facilities for complex numbers, which includes common mathematical functions for types COMPLEX and LONGCOMPLEX.

Instances of the following two classes are used to represent complex numbers:

Data type: COMPLEX = POINTER TO COMPLEXDesc
The real and imaginary parts of this type are represented as type REAL

Data type: LONGCOMPLEX = POINTER TO LONGCOMPLEXDesc
The real and imaginary parts of this type are represented as type LONGREAL

Please note: To create initial instances of COMPLEX and LONGCOMPLEX, you must use the corresponding CMPLX() function.

The following are instances of the corresponding complex number type. They are provided for convenience and have values that represent the specified complex number:

Read-only Variable: i
The value of i is initialized to CMPLX (0.0, 1.0).

Read-only Variable: one
The value of one is initialized to CMPLX (1.0, 0.0).

Read-only Variable: zero
The value of zero is initialized to CMPLX (0.0, 0.0).

The following functions are provided in either ComplexMath (for COMPLEX) or
LComplexMath (for LONGCOMPLEX):

Function: CMPLX (r, i: REAL): COMPLEX
Function: CMPLX (r, i: LONGREAL): LONGCOMPLEX
This function returns an instance of the corresponding complex number type whose real part has a value of r and imaginary part has a value of i.

Function: Copy (z: COMPLEX): COMPLEX
Function: Copy (z: LONGCOMPLEX): LONGCOMPLEX
This function returns a copy of z.

Please note: This function provides the only reliable way to assign complex number values. If a and b are complex numbers, do not use a := b.

Function: RealPart (z: COMPLEX): REAL
Function: RealPart (z: LONGCOMPLEX): LONGREAL
This function returns the real part of the complex number z.

Function: ImagPart (z: COMPLEX): REAL
Function: ImagPart (z: LONGCOMPLEX): LONGREAL
This function returns the imaginary part of the complex number z.

Function: add (z1, z2: COMPLEX): COMPLEX
Function: add (z1, z2: LONGCOMPLEX): LONGCOMPLEX
This function returns the value of z1 added to z2.

Function: sub (z1, z2: COMPLEX): COMPLEX
Function: sub (z1, z2: LONGCOMPLEX): LONGCOMPLEX
This function returns the value of z2 subtracted from z1.

Function: mul (z1, z2: COMPLEX): COMPLEX
Function: mul (z1, z2: LONGCOMPLEX): LONGCOMPLEX
This function returns the value of z1 multiplied by z2.

Function: div (z1, z2: COMPLEX): COMPLEX
Function: div (z1, z2: LONGCOMPLEX): LONGCOMPLEX
This function returns the value of z1 divided by z2.

Function: abs (z: COMPLEX): REAL
Function: abs (z: LONGCOMPLEX): LONGREAL
This function returns an approximation to the length (also known as the absolute value, or modulus) of z.

Please note: An overflow exception may be raised in this computation, even when the complex number itself is well defined.

Function: arg (z: COMPLEX): REAL
Function: arg (z: LONGCOMPLEX): LONGREAL
This function returns an approximation to the angle that z subtends to the positive real axis in the complex plane. The result will be in radians in the range [-pi, pi]. If the modulus (abs(x)) of z is zero, an exception is raised.

Function: conj (z: COMPLEX): COMPLEX
Function: conj (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the complex conjugate of z.

Function: power (base: COMPLEX; exponent: REAL): COMPLEX
Function: power (base: LONGCOMPLEX; exponent: LONGREAL): LONGCOMPLEX
This function returns an approximation to the value of the number base raised to the power exponent.

Function: sqrt (z: COMPLEX): COMPLEX
Function: sqrt (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the principal square root of z.

Please note: The result is the complex number with an arg() of half the value of the arg() of z, and whose abs() is the positive square root of the abs() of z.

Function: exp (z: COMPLEX): COMPLEX
Function: exp (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the mathematical constant e raised to the power of z.

Function: ln (z: COMPLEX): COMPLEX
Function: ln (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the principal value of the natural logarithm of z.

Function: sin (z: COMPLEX): COMPLEX
Function: sin (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the complex sine of z.

Function: cos (z: COMPLEX): COMPLEX
Function: cos (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the complex cosine of z.

Function: tan (z: COMPLEX): COMPLEX
Function: tan (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the complex tangent of z. If z is an odd multiple of pi/2, an exception is raised.

Function: arcsin (z: COMPLEX): COMPLEX
Function: arcsin (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the principal value of the complex arcsine of z.

Function: arccos (z: COMPLEX): COMPLEX
Function: arccos (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the complex arccosine of z.

Function: arctan (z: COMPLEX): COMPLEX
Function: arctan (z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the complex arctangent of z.
Function: polarToComplex (abs, arg: REAL): COMPLEX
Function: polarToComplex (abs, arg: LONGREAL): LONGCOMPLEX
This function returns an approximation to the complex number with the specified polar coordinates. The result will have a length of abs and angle of arg).

Function: scalarMult (scalar: REAL; z: COMPLEX): COMPLEX
Function: scalarMult (scalar: LONGREAL; z: LONGCOMPLEX): LONGCOMPLEX
This function returns an approximation to the scalar product of scalar with z.

Function: IsCMathException (): BOOLEAN
This function returns TRUE if the current process is in the exceptional execution state because of the raising of the corresponding ComplexMath or LComplexMath exception; otherwise, it returns FALSE.

Random Numbers

"Random number" generating routines, like those provided in module `RandomNumbers', are more correctly called pseudo-random number generators because they have only the appearance of randomness, and actually exhibit a specific, repeatable pattern. However, the generated sequence of numbers should pass certain statistical tests as if it were a truly random sequence.

The algorithm implemented by `RandomNumbers' is "good" in the sense that it passes many of these statistical tests, but it is not necessarily useful in all cases. A different algorithm might be better suited to a particular application simply because the inherent structure of the generated number sequence better satisfies the application's required properties.

Because of the deterministic quality of random number generators, the user is required to specify an initial value, or seed. Sequences generated using the same seed (and the same algorithm) will always produce the same results. To get a different sequence, simply use a different seed. A common way to generate different seeds is to initialize using the system's clock time. (This is not done directly within `RandomNumbers' because then it is not possible to reproduce results, which could cause difficulties during, say, testing and debugging.)

Also note that sequences will repeat themselves eventually. In this case, a sequence will start to repeat after, at most, modulo-1 elements, and possibly much sooner than that.

A complete discussion of random number generating algorithms is beyond the scope of this manual. For more information about the algorithm used in this module, and other random number generators, consult the following references:

Random number generators: good ones are hard to find
S.K. Park and K.W. Miller
Communications of the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201

The Art Of Computer Programming:
Volume 2, Seminumerical Algorithms, Second Edition
Donald E. Knuth
Addison-Wesley Publishing Co., January 1981

Constant: modulo
The determing parameter of the linear congruential generator being used by `RandomNumbers'.

Procedure: GetSeed (VAR seed: LONGINT)
This procedure gets the seed value currently in use by routines in module `RandomNumbers'.

Procedure: PutSeed (seed: LONGINT)
This procedure sets seed as the new seed value for routines in `RandomNumbers'. Any value for seed is allowed, but all values will be mapped into the range [1..modulo-1].

Function: RND (range: LONGINT): LONGINT
This function calculates a new "random" number. range has to be in the range [1..modulo-1], and the result is a number in the interval [0, range-1].

Function: Random (): REAL
This function calculates a new "random" number. The result is a number in the interval [0, 1).

Example:

VAR l: LONGINT;
    r: REAL;

RandomNumbers.PutSeed(314159);

l := RandomNumbers.RND(100);
   => l = 19
l := RandomNumbers.RND(10000);
   => l = 5610
l := RandomNumbers.RND(9999999);
   => l = 6158792
l := RandomNumbers.RND(365);
   => l = 54

RandomNumbers.GetSeed(l);
   => l = 143441039

r := RandomNumbers.Random();
   => r = 0.6225381
r := RandomNumbers.Random();
   => r = 0.9990177
r := RandomNumbers.Random();
   => r = 0.4895853
r := RandomNumbers.Random();
   => r = 0.4605866

RandomNumbers.GetSeed(l);
   => l = 989102265


Go to the first, previous, next, last section, table of contents.