home *** CD-ROM | disk | FTP | other *** search
- (***************************************************************************
-
- $RCSfile: Reals.mod $
- Description: Low-level floating point conversions
-
- Created by: fjc (Frank Copeland)
- $Revision: 1.6 $
- $Author: fjc $
- $Date: 1995/01/26 00:48:34 $
-
- Copyright © 1994, Frank Copeland.
- This file is part of the Oberon-A Library.
- See Oberon-A.doc for conditions of use and distribution.
-
- Log entries are at the end of the file.
-
- ***************************************************************************)
-
- <* MAIN- *> <*$ LongVars+ *>
-
- MODULE Reals;
-
- (*
- ** This module performs low-level operations on REAL and LONGREAL
- ** values. The values are assumed to be in IEEE floating-point format.
- ** At present both REAL and LONGREAL values are 32-bit single-precision
- ** values. In future LONGREAL will be re-implemented as 64-bit
- ** double-precision values.
- **
- ** IEEE single-precision reals have the following format:
- **
- ** SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
- ** 31 23 15 7
- **
- ** S = sign, E = exponent, M = mantissa
- *)
-
- IMPORT SYS := SYSTEM;
-
- (*------------------------------------*)
- PROCEDURE Expo* (x : REAL) : INTEGER;
- (*
- ** This procedure extracts the exponent part of a REAL value. This is
- ** held in bits 23-30.
- *)
-
- BEGIN (* Expo *)
- RETURN SHORT (SYS.LSH (SYS.VAL (LONGINT, x), -23)) MOD 256
- END Expo;
-
- (*------------------------------------*)
- PROCEDURE ExpoL* (x : LONGREAL) : INTEGER;
-
- BEGIN (* ExpoL *)
- RETURN Expo (SHORT (x))
- END ExpoL;
-
- (*------------------------------------*)
- PROCEDURE SetExpo* (e : INTEGER; VAR x : REAL);
- (*
- * This procedure sets the exponent part of a REAL variable. It clears bits
- * 23-30 using SYS.AND() and ORs the exponent onto the cleared area.
- *
- * Broken down into simple expressions, the algorithm is:
- * i := SYS.VAL (LONGINT, x);
- * i := SYS.AND (i, 087FFFFFFH);
- * e := SYS.LSH (e MOD 256, 23);
- * i := SYS.LOR (i, e);
- * x := SYS.VAL (REAL, i)
- *)
-
- BEGIN (* SetExpo *)
- x :=
- SYS.VAL
- ( REAL,
- SYS.LOR
- ( SYS.AND ( SYS.VAL (LONGINT, x), 087FFFFFFH ),
- SYS.LSH (LONG (e MOD 256), 23) ) )
- END SetExpo;
-
- (*------------------------------------*)
- PROCEDURE SetExpoL* (e : INTEGER; VAR x : LONGREAL);
-
- VAR y : REAL;
-
- BEGIN (* SetExpoL *)
- y := SHORT (x); SetExpo (e, y); x := LONG (y)
- END SetExpoL;
-
- (*------------------------------------*)
- PROCEDURE Ten* (e : INTEGER) : REAL;
-
- VAR result : REAL; n : INTEGER;
-
- BEGIN (* Ten *)
- result := 1.0; n := ABS (e);
- WHILE n > 0 DO result := result * 10.0; DEC (n) END;
- IF e >= 0 THEN
- RETURN result
- ELSE
- RETURN 1.0 / result
- END;
- END Ten;
-
- (*------------------------------------*)
- PROCEDURE TenL* (e : INTEGER) : LONGREAL;
-
- BEGIN (* TenL *)
- RETURN LONG (Ten (e))
- END TenL;
-
- (*------------------------------------*)
- PROCEDURE Convert* (x : REAL; n : INTEGER; VAR d : ARRAY OF CHAR);
- (*
- * Converts a REAL into a string. d will contain the n most significant
- * digits of x, in REVERSE order.
- *)
-
- VAR i : LONGINT;
-
- BEGIN (* Convert *)
- i := 0;
- REPEAT
- d [i] := CHR (ENTIER (x) MOD 10 + 30H); x := x / 10; INC (i)
- UNTIL i = n;
- END Convert;
-
- (*------------------------------------*)
- PROCEDURE ConvertL* (x : LONGREAL; n : INTEGER; VAR d : ARRAY OF CHAR);
-
- BEGIN (* ConvertL *)
- Convert (SHORT (x), n, d)
- END ConvertL;
-
- (*------------------------------------*)
- PROCEDURE ConvertH* (x : REAL; VAR d : ARRAY OF CHAR);
- (*
- * Converts a REAL into a hexadecimal string.
- *)
-
- VAR i, j, k : LONGINT;
-
- BEGIN (* ConvertH *)
- d [7] := 0X; (* This should cause an index trap if d is too small. *)
- (* Turn off index checking now, since we know there is enough room. *)
- <*$ < IndexChk- *>
- k := SYS.VAL (LONGINT, x);
- i := 8;
- REPEAT
- DEC (i);
- IF k # 0 THEN
- j := k MOD 10H; k := k DIV 10H;
- IF j < 10 THEN d [i] := CHR (j + 30H) ELSE d [i] := CHR (j + 37H) END
- ELSE
- d [i] := "0"
- END;
- UNTIL i = 0;
- <*$ > *>
- END ConvertH;
-
- (*------------------------------------*)
- PROCEDURE ConvertHL* (x : LONGREAL; VAR d : ARRAY OF CHAR);
-
- BEGIN (* ConvertHL *)
- ConvertH (SHORT (x), d)
- END ConvertHL;
-
- END Reals.
-
- (***************************************************************************
-
- $Log: Reals.mod $
- Revision 1.6 1995/01/26 00:48:34 fjc
- - Release 1.5
-
- Revision 1.5 1994/11/11 17:00:38 fjc
- - Uses new external code interface.
-
- Revision 1.5 1994/11/11 17:00:38 fjc
- - Uses new external code interface.
-
- Revision 1.4 1994/09/18 21:25:47 fjc
- - Converted switches to pragmas/options
-
- Revision 1.1 1994/01/15 21:39:12 fjc
- - Start of revision control
-
- ***************************************************************************)
-