Why does rounding not work if I try to compile following code using the FreePascal Compiler?
program RangeCheckError;
var
result: integer;
begin
result := round(1.6514384080961258e+21);
writeln(result);
end.
I get an error message:
round_error.pas(5,15) Error: range check error while evaluating constants ( 1.65143840809612579994E+0021 must be between -9223372036854775808.49.. and 9223372036854775807.49..)
round_error.pas(9) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Why does rounding not work if I try to compile following code using the FreePascal Compiler?
program RangeCheckError;
var
result: integer;
begin
result := round(1.6514384080961258e+21);
writeln(result);
end.
I get an error message:
round_error.pas(5,15) Error: range check error while evaluating constants ( 1.65143840809612579994E+0021 must be between -9223372036854775808.49.. and 9223372036854775807.49..)
round_error.pas(9) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
Share
Improve this question
edited Mar 22 at 19:03
Kai Burghardt
1,6081 gold badge12 silver badges28 bronze badges
asked Mar 22 at 10:48
Bogdan DoroschenkoBogdan Doroschenko
1211 silver badge6 bronze badges
1
- 1 Hi, I guess outside that range the float value does not contain any information about fractions that could be rounded. So if it worked in pascal you would get the input. Pascal seems to be defensive about that and tells that the call to the function does not make sense. If you don't like that behaviour, you could just wrap your own function with a range check around round to avoid the exception. – jottbe Commented Mar 22 at 11:06
1 Answer
Reset to default 1
round(r)
yields a value such that ifr >= 0
thenround(r) = trunc(r + 0.5)
, and ifr < 0
thenround(r) = trunc(r − 0.5)
. It is an error if no such value exists.
Source: Jensen, Kathleen; Wirth, Niklaus. Pascal – user manual and report (4th revised ed.). p. 193. doi:10.1007/978‑1‑4612‑4450‑9. ISBN 978‑0‑387‑97649‑5.
What does “no such value exists” mean?
It means the result of round
must be a valid value of the codomain data type integer
.
The data type integer
comprises (at least) all integral values in the closed range −maxInt
through +maxInt
.
If you supply a value exceeding +maxInt
, more specifically maxInt + 0.499999…8
, the round
function should – if it was mathematically correct – return a value exceeding maxInt
.
This is a nonexistent value, though, hence the error.
1.62… × 1021 > 9.22… × 1018.
NB:
In its default configuration the FreePascal Compiler does not adhere to the ISO standards:
round
uses banker’s rounding (½ rounds to even number), not the rounding method described by Jensen and Wirth in the above quote.
Moreover, the integer
data type does not necessarily provide the largest magnitude.
You need to replace integer
with ALUSInt
.
Otherwise you get a range‐check error because the destination variable’s data type cannot (necessarily) store (all) values round
returns.
To add insult to injury, in FreePascal +maxInt
is high(ALUSInt)
and −maxInt
is low(ALUSInt)
.