<<>> <> <> <> <> <> DIRECTORY DReal, Real, Basics, Scaled USING [IntRep, UMINUS, ValRep, Value]; ScaledImpl: CEDAR PROGRAM IMPORTS DReal, Real, Basics, Scaled EXPORTS Scaled ~ BEGIN OPEN Scaled; bitsPerWord: INTEGER = Basics.bitsPerWord; Negative: PROC [a: Value] RETURNS [BOOL] = INLINE {RETURN [IntRep[a] < 0]}; TIMES: PUBLIC PROC [a, b: Value] RETURNS [Value] = { pos: BOOLEAN ¬ Negative[a] = Negative[b]; prod: Value; IF Negative[a] THEN a ¬ UMINUS[a]; IF Negative[b] THEN b ¬ UMINUS[b]; prod.lo ¬ Basics.HighHalf[LONG[a.lo]*b.lo + (CARDINAL[LAST[INT16]]+1)]; prod.hi ¬ a.hi * b.hi; prod ¬ LOOPHOLE[ LOOPHOLE[prod, LONG CARDINAL] + LONG[a.hi]*b.lo + LONG[a.hi]*b.lo ]; RETURN[IF pos THEN prod ELSE UMINUS[prod]]; }; DIVIDE: PUBLIC PROC [a, b: Value] RETURNS [Value] = { RETURN[FromReal[Float[a]/Float[b]]]; }; FromReal: PUBLIC PROC [real: REAL] RETURNS [Value] = { RETURN[ValRep[Real.Round[Real.FScale[real, BITS[CARD16]]]]] }; Float: PUBLIC PROC [a: Value] RETURNS [REAL] = { RETURN[Real.FScale[IntRep[a], -BITS[CARD16]]] }; Halve: PUBLIC PROC [a: Value] RETURNS [Value] = { RETURN [ValRep[DReal.Round[DREAL[IntRep[a]]*DREAL[0.5]]]]; }; Scale: PUBLIC PROC [a: Value, scale: INTEGER] RETURNS [Value] = { RETURN [ValRep[DReal.Round[DReal.FScale[DREAL[IntRep[a]], scale]]]]; }; END.