-- Copyright (C) 1986 by Xerox Corporation. All rights reserved.
-- LibmSupportImpl.mesa
-- NFS 22-Apr-86 16:27:27
-- Support functions for libm floating pt. functions, and library functions
-- ldexp(), modf(), fabs(), fmod(), and abs().
DIRECTORY
DoubleIeee,
DoubleReal,
DoubleRealFns,
DoubleRealOps,
Inline,
Libm,
LibmSupport;
LibmSupportImpl: PROGRAM
IMPORTS DoubleIeee, DoubleReal, DoubleRealFns, DoubleRealOps, Inline
EXPORTS Libm, LibmSupport =
{
OPEN DoubleReal, DoubleIeee;
copysign: PUBLIC PROCEDURE [x, y: Double] RETURNS [Double] = {
a: VeryLongNumber ← LOOPHOLE[x];
b: VeryLongNumber = LOOPHOLE[y];
IF DblBitOn[b.hi, DblHiBit] THEN -- y is negative
a.hi ← Inline.DBITOR[a.hi, DblHiBit]
ELSE -- y is positive
a.hi ← Inline.DBITAND[a.hi, DblNotHiBit];
RETURN[LOOPHOLE[a]];
};
scalb: PUBLIC PROCEDURE [x: Double, N: INTEGER] RETURNS [Double] = {
a: DblExt ← UnpackDbl[x];
a.exp ← a.exp + N;
IF a.exp >= DblNaNExponent THEN a.det.type ← infinity;
RETURN[PackDbl[@a]];
};
ldexp: PUBLIC PROCEDURE [x: Double, exp: INTEGER] RETURNS [Double] = {
RETURN[scalb[x, exp]]; };
logb: PUBLIC PROCEDURE [x: Double] RETURNS [Double] = {
a: DblExt = UnpackDbl[x];
SELECT a.det.type FROM
zero => RETURN[MinusInfinity];
infinity => RETURN[PlusInfinity];
nan => RETURN[x];
ENDCASE => RETURN[DFloat[LONG[a.exp]]];
};
finite: PUBLIC PROCEDURE [x: Double] RETURNS [INTEGER] = {
true: INTEGER = 1;
false: INTEGER = 0;
RETURN[
IF Inline.DBITAND[LOOPHOLE[x, VeryLongNumber].hi, DblExponentMask] =
DblExponentMask THEN false ELSE true];
};
drem: PUBLIC PROCEDURE [x, p: Double] RETURNS [Double] = {
RETURN[DoubleReal.DFRem[x, p]]; };
modf: PUBLIC PROCEDURE [d: Double, iptr: LONG POINTER TO Double]
RETURNS [Double] = {
fixMode: DoubleRealOps.Mode = [round: rz, traps: DoubleReal.NoExceptions];
iptr↑ ← DoubleRealOps.DRoundF[d, fixMode];
RETURN[DoubleReal.DFSub[d,iptr↑]];
};
fabs: PUBLIC PROCEDURE [d: Double] RETURNS [Double] = {
LOOPHOLE[d, VeryLongNumber].hi ← Inline.DBITAND[
LOOPHOLE[d, VeryLongNumber].hi, DblNotHiBit];
RETURN[d];
};
fmod: PUBLIC PROCEDURE [x, y: Double] RETURNS [Double] = {
IF y = PlusZero OR y = MinusZero THEN RETURN[x]
<<Definition of fmod (when y # 0) is not clear.
The definition used here makes the Rapa validation test pass.>>
ELSE {
py: Double = fabs[y];
rem: Double ← DFRem[fabs[x], py];
-- If rem < 0 then add py.
IF DblBitOn[LOOPHOLE[rem, VeryLongNumber].hi, DblHiBit] AND rem # MinusZero
THEN rem ← DFAdd[rem, py];
RETURN[copysign[rem, x]];
};
};
abs: PUBLIC PROCEDURE [i: INTEGER] RETURNS [INTEGER] = {RETURN[ABS[i]]; };
sqrt: PUBLIC PROCEDURE [x: Double] RETURNS [Double] = {
RETURN[DoubleRealFns.SqRt[x]]; };
}.