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