[fpc-pascal] math round vs banker's round

Sven Barth pascaldragon at googlemail.com
Wed Aug 14 09:38:42 CEST 2013


Am 14.08.2013 08:38, schrieb Ludo Brands:
> On 08/14/2013 08:03 AM, Sven Barth wrote:
>> Am 13.08.2013 23:48 schrieb "David Emerson" <dle3ab at angelbase.com
>> <mailto:dle3ab at angelbase.com>>:
>>> Hi all,
>>>
>>> I have just discovered that the system.round function has this very
>> odd behavior of rounding towards an even number when the fractional part
>> is .5 -- in the system.round documentation this is described as
>> "banker's rounding"
>>> I do not like this behavior. How can I use a more
>> mathematically-traditional round function, which always rounds .5 up,
>> and everything below .5 down?
>>> Do I need to write this function myself?
>> Take a look at SetRoundMode in unit Math:
>> http://www.freepascal.org/docs-html/rtl/math/setroundmode.html
>>
> None of the round modes gives the result OP wants. Furthermore,
> SetRoundMode is a runtime setting and
>    writeln(round(0.5));
>    writeln(round(1.5));
> results in
> 0
> 2
> The compiler hard codes (x64) a movabs $0x0,%rdx and
> movabs $0x2,%rdx
There are three problems:
- if you use constants then the compiler will do the rounding at compile 
time and not take into account the rounding mode (which in my opinion 
can be considered a bug)
- 0.5 does not always have a direct representation as a floating point 
value and thus internally it might be 0.4999999 or something like that 
and thus it will be rounded to 0.4 (see also 
http://bugs.freepascal.org/view.php?id=24374 )
- the rounding system and also most FPUs don't support that "normal 
rounding" the OP wants and thus FPC doesn't implement it either (didn't 
know up to now that banker's rounding is not the same as the rounding I 
learned at school...)

Regards,
Sven



More information about the fpc-pascal mailing list