home *** CD-ROM | disk | FTP | other *** search
- MODULE ExMathLib0;
-
- IMPORT LR := LongRealConversions, LM := MathIEEEDoubTrans,
- X := ExNumbers;
-
- VAR
- ToRadians : X.ExNumType;
- ToDegrees : X.ExNumType;
- Fact500 : X.ExNumType;
- Fact1000 : X.ExNumType;
- Fact2000 : X.ExNumType;
- Fact3000 : X.ExNumType;
-
-
- PROCEDURE ExNumToLongReal*(x : X.ExNumType) : LONGREAL;
- VAR
- Num : LONGREAL;
- Str : ARRAY 81 OF CHAR;
- BEGIN
- (* Convert ExNum into LONGREAL via a string *)
- X.ExNumToStr(x, 0, 0, Str);
- IF LR.StringToReal(Str, Num) THEN
- RETURN Num;
- ELSE
- RETURN 0.0D;
- END;
- END ExNumToLongReal;
-
-
- PROCEDURE LongRealToExNum*(x : LONGREAL; VAR Result : X.ExNumType);
- VAR
- Str : ARRAY 81 OF CHAR;
- BEGIN
- (* Convert LONGREAL into an ExNum via a string *)
- IF LR.RealToString(x, Str, 1, 52, TRUE) THEN
- X.StrToExNum(Str, Result);
- ELSE
- Result := X.Ex0;
- END;
- END LongRealToExNum;
-
-
- PROCEDURE xtoi*(VAR Result : X.ExNumType; x : X.ExNumType; i : LONGINT);
- (* From Knuth, slightly altered : p442, The Art Of Computer Programming, Vol 2 *)
- VAR
- Y : X.ExNumType;
- negative : BOOLEAN;
- BEGIN
- Y := X.Ex1;
- negative := i < 0;
- i := ABS(i);
- LOOP
- IF ODD(i) THEN X.ExMult(Y, Y, x) END;
- i := i DIV 2;
- IF i = 0 THEN EXIT END;
- X.ExMult(x, x, x);
- END;
- IF negative THEN
- X.ExDiv(Result, X.Ex1, Y);
- ELSE
- Result := Y;
- END;
- END xtoi;
-
-
- PROCEDURE Root *(VAR Result : X.ExNumType;
- x : X.ExNumType;
- i : LONGINT);
- (* Use iterative solution of a general root equation *)
- VAR
- y, yp, f, g, t : X.ExNumType;
- iteration : INTEGER;
- root : LONGREAL;
- negate : BOOLEAN;
- BEGIN
- IF ((x.Sign = X.negative) & ~ODD(i)) OR (i < 2) THEN
- X.ExStatus := X.IllegalNumber;
- Result := X.Ex0;
- ELSIF X.IsZero(x) THEN
- Result := x;
- ELSE
- (* handle negative roots *)
- IF x.Sign = X.negative THEN X.ExAbs(x); negate := TRUE
- ELSE negate := FALSE
- END;
-
- (* estimate of the ith root *)
- root := 1.0D / i;
- LongRealToExNum(LM.Pow(root,ExNumToLongReal(x)), yp);
- X.ExNumb(i, 0, 0, f); (* i *)
- X.ExNumb(i-1, 0, 0, g); (* i - 1 *)
-
- (* calculate the root *)
- iteration := 4;
- LOOP
- (* y := 1/i * (yp * (i-1) + x / yp^(i-1)) *)
- xtoi(t, yp, i-1); (* yp**(i-1) *)
- X.ExMult(y, t, yp); (* yp**i *)
- X.ExMult(y, y, g); (* yp**i * (i-1) *)
- X.ExAdd(y, y, x); (* yp**i * (i-1) + x *)
- X.ExMult(t, t, f); (* yp**(i-1) * i *)
- X.ExDiv(y, y, t);
- IF (X.ExCompare(y, yp) = X.ExEqual) OR (iteration = 0) THEN EXIT END;
- DEC(iteration);
- yp := y;
- END;
-
- (* adjust the number's sign *)
- Result := y;
- IF negate THEN X.ExChgSign(Result) END;
- END;
- END Root;
-
-
- PROCEDURE powerof10(VAR Result : X.ExNumType; x : LONGINT);
- BEGIN
- X.ExNumb(1, 0, SHORT(x), Result);
- END powerof10;
-
-
- PROCEDURE RadToDegX*(VAR radianAngle : X.ExNumType);
- (* Convert a radian measure into degrees *)
- BEGIN
- X.ExMult(radianAngle, ToDegrees, radianAngle);
- END RadToDegX;
-
-
- PROCEDURE DegToRadX*(VAR radianAngle : X.ExNumType);
- (* Convert a degree measure into radians *)
- BEGIN
- X.ExMult(radianAngle, ToRadians, radianAngle);
- END DegToRadX;
-
-
- PROCEDURE sqrtX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- Root(Result, x, 2);
- END sqrtX;
-
-
- PROCEDURE lnX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Log(ExNumToLongReal(x)), Result);
- END lnX;
-
-
- PROCEDURE logX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Log10(ExNumToLongReal(x)), Result);
- END logX;
-
-
- PROCEDURE factorial(VAR prevn, currentn : LONGINT;
- VAR PrevFact, Result : X.ExNumType);
- (* Implements an incremental factorial using a previously calculated value. *)
- VAR
- i : LONGINT;
- BEGIN
- FOR i := prevn+1 TO currentn DO
- (* PrevFact := PrevFact * i; *)
- X.ExNumb(i, 0, 0, Result);
- X.ExMult(PrevFact, PrevFact, Result);
- END;
- prevn := currentn;
- Result := PrevFact;
- END factorial;
-
-
- PROCEDURE factorialX*(VAR Result : X.ExNumType; n : LONGINT);
- CONST
- MaxFactorial = 3249;
- VAR
- fact : LONGINT;
- prev : X.ExNumType;
- BEGIN
- IF (n < 0) OR (n > MaxFactorial) THEN
- X.ExStatus := X.IllegalNumber;
- Result := X.Ex0;
- RETURN;
- END;
- IF n < 500 THEN prev := X.Ex1; fact := 0
- ELSIF n < 1000 THEN prev := Fact500; fact := 500
- ELSIF n < 2000 THEN prev := Fact1000; fact := 1000
- ELSIF n < 3000 THEN prev := Fact2000; fact := 2000
- ELSE prev := Fact3000; fact := 3000
- END;
- factorial(fact, n, prev, Result);
- END factorialX;
-
-
- PROCEDURE expX*(VAR Result : X.ExNumType; x : X.ExNumType);
- VAR
- xPower : LONGREAL;
- BEGIN
- xPower := ExNumToLongReal(x);
- X.ExFrac(x);
- IF (ABS(xPower) < MAX(LONGINT)) & X.IsZero(x) THEN
- xtoi(Result, X.e, ENTIER(xPower));
- ELSE
- LongRealToExNum(LM.Exp(xPower), Result);
- END;
- END expX;
-
-
- PROCEDURE powerX*(VAR Result : X.ExNumType; x, y : X.ExNumType);
- VAR
- yPower : LONGREAL;
- BEGIN
- yPower := ExNumToLongReal(y);
- X.ExFrac(y);
- IF (ABS(yPower) < MAX(LONGINT)) & X.IsZero(y) THEN
- xtoi(Result, x, ENTIER(yPower));
- ELSE
- LongRealToExNum(LM.Pow(yPower,ExNumToLongReal(x)),Result);
- END;
- END powerX;
-
-
- PROCEDURE rootX*(VAR Result : X.ExNumType; x, y : X.ExNumType);
- VAR
- yRoot : LONGREAL;
- BEGIN
- yRoot := ExNumToLongReal(y);
- X.ExFrac(y);
- IF (ABS(yRoot) < MAX(LONGINT)) & X.IsZero(y) THEN
- Root(Result, x, ENTIER(yRoot));
- ELSE
- yRoot := 1.0D / yRoot;
- LongRealToExNum(LM.Pow(yRoot,ExNumToLongReal(x)),Result);
- END;
- END rootX;
-
-
- PROCEDURE sinX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Sin(ExNumToLongReal(x)), Result);
- END sinX;
-
-
- PROCEDURE cosX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Cos(ExNumToLongReal(x)), Result);
- END cosX;
-
-
- PROCEDURE tanX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Tan(ExNumToLongReal(x)), Result);
- END tanX;
-
-
- PROCEDURE arctanX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Atan(ExNumToLongReal(x)), Result);
- END arctanX;
-
-
- PROCEDURE coshX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Cosh(ExNumToLongReal(x)), Result);
- END coshX;
-
-
- PROCEDURE sinhX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Sinh(ExNumToLongReal(x)), Result);
- END sinhX;
-
-
- PROCEDURE tanhX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Tanh(ExNumToLongReal(x)), Result);
- END tanhX;
-
-
- PROCEDURE arccoshX*(VAR Result : X.ExNumType; x : X.ExNumType);
- VAR
- Temp : X.ExNumType;
- BEGIN
- (* Result = ln(x + sqrt(x*x - 1)) *)
- X.ExMult(Temp, x, x);
- X.ExSub(Temp, Temp, X.Ex1);
- sqrtX(Temp, Temp);
- X.ExAdd(Temp, x, Temp);
- lnX(Result, Temp);
- END arccoshX;
-
-
- PROCEDURE arcsinhX*(VAR Result : X.ExNumType; x : X.ExNumType);
- VAR
- Temp : X.ExNumType;
- BEGIN
- (* Result = ln(x + sqrt(x*x + 1)) *)
- X.ExMult(Temp, x, x);
- X.ExAdd(Temp, Temp, X.Ex1);
- sqrtX(Temp, Temp);
- X.ExAdd(Temp, x, Temp);
- lnX(Result, Temp);
- END arcsinhX;
-
-
- PROCEDURE arctanhX*(VAR Result : X.ExNumType; x : X.ExNumType);
- VAR
- Temp, Temp2 : X.ExNumType;
- BEGIN
- (* Result = ln((1 + x) / (1 - x)) / 2 *)
- X.ExAdd(Temp, X.Ex1, x);
- X.ExSub(Temp2, X.Ex1, x);
- X.ExDiv(Temp, Temp, Temp2);
- lnX(Result, Temp);
- X.ExNumb(0, 5, 0, Temp);
- X.ExMult(Result, Result, Temp);
- END arctanhX;
-
-
- PROCEDURE arcsinX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- LongRealToExNum(LM.Asin(ExNumToLongReal(x)), Result);
- END arcsinX;
-
-
- PROCEDURE arccosX*(VAR Result : X.ExNumType; x : X.ExNumType);
- BEGIN
- (* Replacement algorithm *)
- LongRealToExNum(LM.Acos(ExNumToLongReal(x)), Result);
- END arccosX;
-
-
- BEGIN
- (* Initialize a few internal conversion constants *)
- X.StrToExNum(
- "5.729577951308232087679815481410517033240547246656420E+1",
- ToDegrees);
- X.StrToExNum(
- "1.745329251994329576923690768488612713442871888541727E-2",
- ToRadians);
-
- (* Speed up very large factorials *)
- X.StrToExNum(
- "1.220136825991110068701238785423046926253574342803193E+1134",
- Fact500);
- X.StrToExNum(
- "4.023872600770937735437024339230039857193748642107146E+2567",
- Fact1000);
- X.StrToExNum(
- "3.316275092450633241175393380576324038281117208105780E+5735",
- Fact2000);
- X.StrToExNum(
- "4.149359603437854085556867093086612170951119194931810E+9130",
- Fact3000);
- END ExMathLib0.
-