Actions
Defect #673
openReal procedure in obl.out.mod overflows for large values
Status:
New
Priority:
Normal
Category:
Oberon Library
Target version:
-
% Done:
0%
Description
If the whole part of REAL
value is larger than what can fit in LONGINT
the procedure fails.
I have ported some code from Modula-2 which implements this functionality
which may be an inspiration solve this issue.
This is still very simple, but seems to work OK and is probably good enough
for debug printing.
MODULE Test; CONST MaxRoundArray = 17; VAR RoundValue : ARRAY MaxRoundArray OF REAL; PROCEDURE FormatFix(VAR str : ARRAY OF CHAR; value : REAL; prec: INTEGER); VAR i, digits, round, val : INTEGER; BEGIN IF (prec <= 0) OR (prec > 17) THEN prec := 17 END; IF value < 0 THEN value := ABS(value); ArrayOfChar.AppendChar(str, '-'); END; (* force real to less than 10 *) round := prec; digits := 1; WHILE value >= 10.0 DO IF value >= 1.0E4 THEN value := value / 1.0E4; INC(digits, 4); ELSIF value >= 1.0E2 THEN value := value / 1.0E2; INC(digits, 2); ELSE value := value / 10.0; INC(digits, 1); END; END; (* round off *) round := prec + (digits - 1); IF round < 0 THEN round := 0 ELSIF round > MaxRoundArray - 1 THEN round := MaxRoundArray - 1; END; value := value + RoundValue[round]; IF value >= 10.0 THEN value := value / 10.0; INC(digits); END; (* write digits *) FOR i := 1 TO digits DO val := ENTIER(value); ArrayOfChar.AppendChar(str, CHR(ORD('0') + val MOD 10)); value := 10*(value - val); END; (* write fractional part *) IF prec >= 0 THEN ArrayOfChar.AppendChar(str, '.'); INC(prec, digits); WHILE digits < prec DO val := ENTIER(value); ArrayOfChar.AppendChar(str, CHR(ORD('0') + val MOD 10)); value := 10*(value - val); INC(digits); END; END; END FormatFix; BEGIN RoundValue[0] := 0.5; RoundValue[1] := 5.0E-2; RoundValue[2] := 5.0E-3; RoundValue[3] := 5.0E-4; RoundValue[4] := 5.0E-5; RoundValue[5] := 5.0E-6; RoundValue[6] := 5.0E-7; RoundValue[7] := 5.0E-8; RoundValue[8] := 5.0E-9; RoundValue[9] := 5.0E-10; RoundValue[10] := 5.0E-11; RoundValue[11] := 5.0E-12; RoundValue[12] := 5.0E-13; RoundValue[13] := 5.0E-14; RoundValue[14] := 5.0E-15; RoundValue[15] := 5.0E-16; RoundValue[16] := 5.0E-17; END Test.
No data to display
Actions