Make Reals.Mod independent of INTEGER size and add reals tests.

This commit is contained in:
David Brown 2016-08-17 17:03:36 +01:00
parent 80f5e51789
commit c0d5b8dbfd
6 changed files with 130 additions and 44 deletions

View file

@ -596,11 +596,13 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
PROCEDURE FPrintLReal*(VAR fp: LONGINT; lr: LONGREAL);
VAR l, h: LONGINT;
BEGIN
IF SIZE(REAL) = SIZE(INTEGER) THEN
IF SIZE(LONGREAL) = SIZE(LONGINT) THEN
(* 64 bit LONGINT *)
FPrint(fp, SYSTEM.VAL(LONGINT, lr))
ELSE
(* 32 bit LONGINT *)
SYSTEM.GET(SYSTEM.ADR(lr), l); SYSTEM.GET(SYSTEM.ADR(lr)+4, h);
FPrint(fp, l); FPrint(fp, h)
ELSE
FPrint(fp, SYSTEM.VAL(LONGINT, lr))
END
END FPrintLReal;

View file

@ -1,7 +1,8 @@
MODULE Reals;
(* JT, 5.2.90 / RC 9.12.91 conversion between reals and strings for HP-700, MB 9.12.91, JT for Ofront, 16.3. 95*)
(* DCWB 20160817 Made independent of INTEGER size *)
IMPORT S := SYSTEM;
IMPORT SYSTEM;
PROCEDURE Ten*(e: INTEGER): REAL;
VAR r, power: LONGREAL;
@ -13,7 +14,7 @@ MODULE Reals;
END ;
RETURN SHORT(r)
END Ten;
PROCEDURE TenL*(e: INTEGER): LONGREAL;
VAR r, power: LONGREAL;
@ -26,31 +27,43 @@ MODULE Reals;
power := power * power
END
END TenL;
(* Real number format (IEEE 754)
TYPE REAL - Single precision / binary32:
1/sign, 8/exponent, 23/significand
TYPE LONGREAL - Double precision / binary64:
1/sign, 11/exponent, 52/significand
exponent:
stored as exponent value + 127.
significand (fraction):
excludes leading (most significant) bit which is assumed to be 1.
*)
PROCEDURE Expo*(x: REAL): INTEGER;
VAR i: INTEGER;
BEGIN
RETURN SHORT(ASH(S.VAL(INTEGER, x), -23) MOD 256)
SYSTEM.GET(SYSTEM.ADR(x)+2, i);
RETURN (i DIV 127) MOD 256
END Expo;
PROCEDURE ExpoL*(x: LONGREAL): INTEGER;
VAR i: INTEGER; l: LONGINT;
BEGIN
IF SIZE(INTEGER) = 4 THEN
S.GET(S.ADR(x)+4, i); (* Fetch top 32 bits *)
RETURN SHORT(ASH(i, -20) MOD 2048)
ELSIF SIZE(LONGINT) = 4 THEN
S.GET(S.ADR(x)+4, l); (* Fetch top 32 bits *)
RETURN SHORT(ASH(l, -20) MOD 2048)
ELSE HALT(98)
END
SYSTEM.GET(SYSTEM.ADR(x)+6, i);
RETURN (i DIV 16) MOD 2048
END ExpoL;
(* Convert LONGREAL: Write positive integer value of x into array d.
(* Convert LONGREAL: Write positive integer value of x into array d.
The value is stored backwards, i.e. least significant digit
first. n digits are written, with trailing zeros fill.
first. n digits are written, with trailing zeros fill.
On entry x has been scaled to the number of digits required. *)
PROCEDURE ConvertL*(x: LONGREAL; n: INTEGER; VAR d: ARRAY OF CHAR);
VAR i, j, k: LONGINT;
@ -64,15 +77,15 @@ MODULE Reals;
j := ENTIER(x - (i * 1000000000.0D0)); (* The low 9 digits *)
(* First generate the low 9 digits. *)
IF j < 0 THEN j := 0 END;
WHILE k < 9 DO
WHILE k < 9 DO
d[k] := CHR(j MOD 10 + 48); j := j DIV 10; INC(k)
END;
(* Fall through to generate the upper digits *)
ELSE
(* We can generate all the digits in one go. *)
i := ENTIER(x);
i := ENTIER(x);
END;
WHILE k < n DO
d[k] := CHR(i MOD 10 + 48); i := i DIV 10; INC(k)
END
@ -89,28 +102,26 @@ MODULE Reals;
ELSE RETURN CHR(i+55) END
END ToHex;
PROCEDURE BytesToHex(VAR b, d: ARRAY OF SYSTEM.BYTE);
VAR i: INTEGER; l: LONGINT; by: CHAR;
BEGIN
i := 0; l := LEN(b);
WHILE i < l DO
by := SYSTEM.VAL(CHAR, d[i]);
d[i*2] := ToHex(ORD(by) DIV 16);
d[i*2+1] := ToHex(ORD(by) MOD 16);
INC(i)
END
END BytesToHex;
(* Convert Hex *)
PROCEDURE ConvertH*(y: REAL; VAR d: ARRAY OF CHAR);
TYPE pc4 = POINTER TO ARRAY 4 OF CHAR;
VAR p: pc4; i: INTEGER;
BEGIN
p := S.VAL(pc4, S.ADR(y)); i := 0;
WHILE i<4 DO
d[i*2] := ToHex(ORD(p[i]) DIV 16);
d[i*2+1] := ToHex(ORD(p[i]) MOD 16)
END
BEGIN BytesToHex(y, d)
END ConvertH;
(* Convert Hex Long *)
PROCEDURE ConvertHL*(y: LONGREAL; VAR d: ARRAY OF CHAR);
TYPE pc8 = POINTER TO ARRAY 8 OF CHAR;
VAR p: pc8; i: INTEGER;
BEGIN
p := S.VAL(pc8, S.ADR(y)); i := 0;
WHILE i<8 DO
d[i*2] := ToHex(ORD(p[i]) DIV 16);
d[i*2+1] := ToHex(ORD(p[i]) MOD 16)
END
PROCEDURE ConvertHL*(x: LONGREAL; VAR d: ARRAY OF CHAR);
BEGIN BytesToHex(x, d)
END ConvertHL;
END Reals.

View file

@ -0,0 +1,50 @@
MODULE TestLibrary;
IMPORT SYSTEM, Console, Reals;
PROCEDURE TestConvert(lr: LONGREAL);
VAR str: ARRAY 20 OF CHAR; i: INTEGER;
BEGIN
Reals.ConvertL(lr, 6, str);
i := 6; WHILE i > 0 DO DEC(i); Console.Char(str[i]) END;
Console.Ln;
END TestConvert;
PROCEDURE TestHex(r: REAL);
VAR str: ARRAY 20 OF CHAR;
BEGIN
Reals.ConvertH(r, str); str[8] := 0X; Console.String(str); Console.Ln;
END TestHex;
PROCEDURE RealTests;
VAR
str: ARRAY 20 OF CHAR;
(*
r: REAL;
lr: LONGREAL;
*)
BEGIN
TestConvert(1.0);
TestConvert(1.5);
TestConvert(2.0);
TestConvert(2.99);
TestConvert(3.0);
TestHex(1.0);
TestHex(1.5);
TestHex(2.0);
TestHex(2.99);
TestHex(3.0);
Console.Int(Reals.Expo(0.5),1); Console.Ln; (* 126 *)
Console.Int(Reals.Expo(1.0),1); Console.Ln; (* 128 *)
Console.Int(Reals.Expo(2.0),1); Console.Ln; (* 129 *)
Console.Int(Reals.Expo(3.0),1); Console.Ln; (* 129 *)
Console.Int(Reals.Expo(4.0),1); Console.Ln; (* 130 *)
END RealTests;
BEGIN
RealTests;
Console.String("Library tests successful."); Console.Ln;
END TestLibrary.

View file

@ -0,0 +1,16 @@
000001
000001
000002
000002
000003
33333333
33333333
33333333
33333333
33333333
126
128
129
129
130
Library tests successful.

View file

@ -0,0 +1,6 @@
#!/bin/sh
. ../testenv.sh
# Generate mixed source and assembly code listing
voc TestLibrary.mod -m
./TestLibrary >result
. ../testresult.sh

View file

@ -385,9 +385,10 @@ confidence:
cd src/test/confidence/hello; $(RUNTEST)
cd src/test/confidence/intsyntax; $(RUNTEST)
cd src/test/confidence/language; $(RUNTEST)
if [ "$(PLATFORM)" != "windows" ] ; then cd src/test/confidence/signal; $(RUNTEST); fi
cd src/test/confidence/library; $(RUNTEST)
cd src/test/confidence/lola; $(RUNTEST)
cd src/test/confidence/arrayassignment; $(RUNTEST)
if [ "$(PLATFORM)" != "windows" ] ; then cd src/test/confidence/signal; $(RUNTEST); fi
@printf "\n\n--- Confidence tests passed ---\n\n"