Real.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Stewart, September 1, 1982 10:03 am
Rovner, May 13, 1983 1:13 pm
Levin, August 8, 1983 4:15 pm
Russ Atkinson (RRA) February 19, 1985 5:03:31 pm PST
Doug Wyatt, February 25, 1985 3:25:02 pm PST
DIRECTORY
Basics USING [Comparison],
PrincOps USING [zINC, zMISC, aFIX, aFIXI, aFIXC, aROUND, aROUNDI, aROUNDC, aFREM, aFSQRT, aFCOMP, aFADD, aFSUB, aFMUL, aFDIV, aFLOAT, aFSC];
Operations on REAL numbers.
See IEEE floating point standard for more information.
Real: CEDAR DEFINITIONS
= BEGIN
Operations
Fix:
PROC [
REAL]
RETURNS [
INT] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFIX;
};
... converts REAL to INT by truncating (mode rz).
FixLI:
PROC [
REAL]
RETURNS [
INT] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFIX;
};
... same as Fix (LI stands for LONG INTEGER).
FixI:
PROC [
REAL]
RETURNS [
INTEGER] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFIXI;
};
... converts REAL to INTEGER by truncating (mode rz).
FixC:
PROC [
REAL]
RETURNS [
CARDINAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFIXC;
};
... converts REAL to CARDINAL by truncating (mode rz).
Round:
PROC [
REAL]
RETURNS [
INT] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aROUND;
};
... converts REAL to INT by rounding (mode rn).
RoundLI:
PROC [
REAL]
RETURNS [
INT] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aROUND;
};
... same as Round (LI stands for LONG INTEGER).
RoundI:
PROC [
REAL]
RETURNS [
INTEGER] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aROUNDI;
};
... converts REAL to INTEGER by rounding (mode rn).
RoundC:
PROC [
REAL]
RETURNS [
CARDINAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aROUNDC;
};
... converts REAL to CARDINAL by rounding (mode rn).
CompareREAL:
PROC [a, b:
REAL]
RETURNS [Basics.Comparison] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFCOMP;
PrincOps.zINC;
};
... compares two REALs.
SqRt:
PROC [
REAL]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFSQRT;
};
Square root. Note that RealFns.SqRt is probably faster.
FRem:
PROC [a, b:
REAL]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFREM;
};
Remainder of a/b. Caution: this is currently unimplemented!
The following are normally generated by the compiler.
FAdd:
PROC [a, b:
REAL]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFADD;
}; -- a+b
FSub:
PROC [a, b:
REAL]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFSUB;
}; -- a-b
FMul:
PROC [a, b:
REAL]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFMUL;
}; -- a*b
FDiv:
PROC [a, b:
REAL]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFDIV;
}; -- a/b
FComp:
PROC [a, b:
REAL]
RETURNS [
INTEGER] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFCOMP;
}; -- (a<b) => -1, (a=b) => 0, (a>b) => +1
FScale:
PROC [a:
REAL, scale:
INTEGER]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFSC;
}; -- a*(2^scale)
Float:
PROC [i:
INT]
RETURNS [
REAL] =
TRUSTED
MACHINE
CODE {
PrincOps.zMISC, PrincOps.aFLOAT;
}; -- REAL[i]
Decimal conversion
MaxSinglePrecision:
CARDINAL = 9;
# of decimal places needed to always exactly reproduce the given real number.
DefaultSinglePrecision:
CARDINAL = 7;
# of decimal places that are normally fully significant
PairToReal:
PROC [fr:
INT, exp10:
INTEGER]
RETURNS [
REAL];
... converts the value fr*10**exp10 to real.
RealToPair:
PROC [r:
REAL, precision:
NAT ← DefaultSinglePrecision]
RETURNS [type: NumberType, fr:
INT, exp10:
INTEGER];
... converts value r to fr*10**exp10; fr will have precision significant digits.
Constants
PlusZero: REAL = LOOPHOLE[LONG[00000000000B]];
MinusZero: REAL = LOOPHOLE[20000000000B];
PlusInfinity: REAL = LOOPHOLE[17740000000B];
MinusInfinity: REAL = LOOPHOLE[37740000000B];
LargestNumber: REAL = LOOPHOLE[17737777777B]; -- almost infinity
SmallestNormalizedNumber: REAL = LOOPHOLE[00040000000B];
NonTrappingNaN: REAL = LOOPHOLE[17740000001B];
TrappingNaN:
REAL =
LOOPHOLE[17740000002B];
You may want to use TrappingNaN to initialize storage.
TrapNonTrappingNaN: LONG CARDINAL = LONG[1];
TrapTrappingNaN: LONG CARDINAL = LONG[2];
AddInfinityNaN: LONG CARDINAL = LONG[3];
MultiplyInfinityNaN: LONG CARDINAL = LONG[4];
DivideInfinityNaN: LONG CARDINAL = LONG[5];
SqRtNaN:
LONG
CARDINAL =
LONG[6];
These values may be encountered as vp.frac during an exception.
Exceptions
Flag:
TYPE =
BOOL ←
FALSE;
Exception:
TYPE =
MACHINE
DEPENDENT{
fixOverflow, inexactResult, invalidOperation, divisionByZero, overflow, underflow};
ExceptionFlags:
TYPE =
PACKED
ARRAY Exception
OF Flag;
NoExceptions: ExceptionFlags = ALL[FALSE];
AllExceptions: ExceptionFlags = ALL[TRUE];
UsualExceptions: ExceptionFlags = [
fixOverflow: TRUE,
invalidOperation: TRUE,
divisionByZero: TRUE,
overflow: TRUE
];
NumberType:
TYPE =
MACHINE
DEPENDENT { normal, zero, infinity, nan };
Extended:
TYPE =
RECORD [
type: NumberType,
sign: BOOL, exp: INTEGER, frac: LONG CARDINAL
];
Extended is the internal form of a single precision floating point number. If the type of a value is infinity or zero, only the sign is interesting. In these cases, exp and frac are undefined. If type = nan, then exp is undefined and frac contains the nan significand. Some constant nans are defined above. If type = normal, then sign, exp, and frac describe the value: if sign is true, then the number is negative; exp is the binary exponent; frac is the significand (the binary point is between bits 0 and 1 - normalized numbers are between 1 and 2).
RealException: SIGNAL [flags: ExceptionFlags, vp: REF Extended]
RETURNS [clientFixup: BOOL ← FALSE];
RealError:
ERROR;
RealException is raised if any enabled exception occurs. Flags reports all the exceptions which occurred during the faulted operation (including those which are disabled). On RESUME, if clientFixup is TRUE, the client is expected to have fixed up the reference. If clientFixup is FALSE the standard fixup will happen. Operations in this interface only raise RealException on the conditions mentioned in UsualExceptions, above. Usually, RealException can be resumed, but certain exceptions, such as invalidOperation raised as a result of compare or one of the Fixes, cannot be resumed. If a RESUME is done in such a case, the ERROR RealError is raised.
GetStickyFlags: PROC RETURNS [ExceptionFlags];
SetStickyFlags:
PROC [new: ExceptionFlags ← NoExceptions]
RETURNS [old: ExceptionFlags];
The six kinds of exceptions have independent "sticky" flags that remember if the exception has occurred since the last call to SetStickyFlags. SetStickyFlags is provided so that procedures may save and restore the state for others.
END.
4-Feb-81 18:42:11, L. Stewart, fixed TrappingNaN to be of type REAL
June 3, 1982 10:36 am, L. Stewart, added REF, SqRt, FScale, removed STRING
September 1, 1982 10:03 am, L. Stewart, CompareREAL, Cedar 3.4
May 13, 1983 1:13 pm, Paul Rovner, conversion to Cedar 5.0
Russ Atkinson (RRA) February 19, 1985 5:02:31 pm PST
General cleanup, especially to improve readability
Doug Wyatt, February 25, 1985 2:17:58 pm PST
More cleanup. Removed initialization stuff.