最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

floating point - Why doesn’t rounding work outside of range? - Stack Overflow

programmeradmin4浏览0评论

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
Add a comment  | 

1 Answer 1

Reset to default 1

round(r) yields a value such that if r >= 0 then round(r) = trunc(r + 0.5), and if r < 0 then round(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).

发布评论

评论列表(0)

  1. 暂无评论