

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
mathematicallytraditional round function, which always rounds .5 up,
and everything below .5 down?
Do I need to write this function myself?
Thanks!
~David
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


El 13/08/2013 23:47, David Emerson escribió:
> 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
> mathematicallytraditional round function, which always rounds .5 up,
> and everything below .5 down?
>
> Do I need to write this function myself?
Hello,
SimpleRoundTo I think.
Maybe documentation should be changed to add SimpleRoundTo in cross
referenced functions and note that SimpleRoundTo uses classic round
system instead bankers one.

_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


Am 13.08.2013 23:48 schrieb "David Emerson" <[hidden email]>:
>
> 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 mathematicallytraditional 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/docshtml/rtl/math/setroundmode.html
Regards,
Sven
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


On 08/14/2013 08:03 AM, Sven Barth wrote:
> Am 13.08.2013 23:48 schrieb "David Emerson" < [hidden email]
> <mailto: [hidden email]>>:
>>
>> 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
> mathematicallytraditional 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/docshtml/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
Ludo
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


Thanks for the suggestions, guys!
José Mejuto wrote:
> SimpleRoundTo I think.
But I want an integer result, and this returns a floating point.
Sven Barth wrote:
> Take a look at SetRoundMode in unit Math:
> http://www.freepascal.org/docshtml/rtl/math/setroundmode.htmlAfter calling SetRoundMode(rmNearest);
I find that system.round() is still doing banker's rounding. Am I
missing something?
I don't see this TfpuRoundingMode mentioned anywhere in the
documentation, other than the "get" and "set" functions for the same.
What does it effect?
...
Anyway I guess I am going to have to write my own round() function :P
Cheers,
~David.
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


Am 13.08.2013 23:47, schrieb David Emerson:
> 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
> mathematicallytraditional round function, which always rounds .5 up,
> and everything below .5 down?
>
> Do I need to write this function myself?
Just checked again, most FPUs only seem to support "banker's rounding",
"round up", "round down" and "truncate", so these four are the only ones
supported by FPC's and Delphi's rounding mechanism. So if you want
normal mathematical rounding then you'll need to write your own function.
Regards,
Sven
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


Am 14.08.2013 08:47, schrieb David Emerson:
> Thanks for the suggestions, guys!
>
> José Mejuto wrote:
> > SimpleRoundTo I think.
>
> But I want an integer result, and this returns a floating point.
>
> Sven Barth wrote:
>> Take a look at SetRoundMode in unit Math:
>> http://www.freepascal.org/docshtml/rtl/math/setroundmode.html>
> After calling SetRoundMode(rmNearest);
> I find that system.round() is still doing banker's rounding. Am I
> missing something?
rmNearest is banker's rounding.
> I don't see this TfpuRoundingMode mentioned anywhere in the
> documentation, other than the "get" and "set" functions for the same.
> What does it effect?
Just click on TFPURoundingMode mentioned in the link.
>
> ...
> Anyway I guess I am going to have to write my own round() function :P
>
Seems so.
Regards,
Sven
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


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" < [hidden email]
>> <mailto: [hidden email]>>:
>>> 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
>> mathematicallytraditional 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/docshtml/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
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


On 08/14/2013 09:38 AM, Sven Barth wrote:
>
>  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 )
Hmmm
AFAIU, in hardware / memory, the binary representation of 0.5 is
(sign * mantissa * 2 ** exponent ) = (1) * 0.5 * 2 ** 1
so this seems to be "exact"
Maybe the compiler does not calculate exactly this value when doing the
constant "0.5". I don't consider this a problem, as IMHO, in fact any
attempt to rely on an exact value of a floating point number is erroneous.
Michael
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


On 14 Aug 2013, at 09:38, Sven Barth wrote:  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 )
0.5 is one of the values that can always be represented exactly. The fractional part of IEEE 754 floating point numbers is represented as sums of negative powers of 2, i.e. 0.5, 0.25, etc.
Jonas _______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


Am 14.08.2013 10:11, schrieb Jonas
Maebe:
On 14 Aug 2013, at 09:38, Sven Barth wrote:
 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 )
0.5 is one of the values that can always be represented
exactly. The fractional part of IEEE 754 floating point numbers
is represented as sums of negative powers of 2, i.e. 0.5, 0.25,
etc.
It should have been "x.5" instead of "0.5" :)
What's your opinion regarding the point that the compiler does not
handle the rounding mode when "Round" is inlined for constants?
Regards,
Sven
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


Am 14.08.2013 09:55, schrieb Michael Schnell:
> On 08/14/2013 09:38 AM, Sven Barth wrote:
>>
>>  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 )
> Hmmm
>
> AFAIU, in hardware / memory, the binary representation of 0.5 is
>
> (sign * mantissa * 2 ** exponent ) = (1) * 0.5 * 2 ** 1
>
> so this seems to be "exact"
>
> Maybe the compiler does not calculate exactly this value when doing
> the constant "0.5". I don't consider this a problem, as IMHO, in fact
> any attempt to rely on an exact value of a floating point number is
> erroneous.
I wanted to write "x.5" instead of "0.5" :)
Regards,
Sven
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal


On 08/14/2013 10:42 AM, Vincent
Snijders wrote:
For any digit x, it still can be represented exactly in
binary representation ...
Nope,
As the bit count of the mantissa is limited to  say  n , with x
> 2**(n1) you will not have an exact representation of x.5.
Michael
_______________________________________________
fpcpascal maillist  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpcpascal

