[Pharo-project] Unexpected behavior of roundTo:

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri Apr 8 19:30:50 CEST 2011


Pour enfoncer le clou, let's play a bit more with inexact representations:

{
((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8
predecessor)) abs -> -1.
((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8)) abs -> 0.
((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8 successor)) abs -> 1.
} detectMin: [:e | e key ]

you get 0.0->1, which mean that:
  (2.8 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat = (2.8 successor)

But remember:
  (2.8 asTrueFraction roundTo: 0.01 asTrueFraction) ~= (2.8 successor)

It must be interpreted as: the nearest Float to (2.8 asTrueFraction
roundTo: 0.01 asTrueFraction) is
(2.8 successor).

If you want to know how far it is, then get an idea with:

((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8 successor)
asTrueFraction) asFloat
 -2.0816681711721685e-16

Nicolas

2011/4/8 Schwab,Wilhelm K <bschwab at anest.ufl.edu>:
> +1.  This seems like an extension of "never test equality on floats."
>
>
>
> ________________________________________
> From: pharo-project-bounces at lists.gforge.inria.fr [pharo-project-bounces at lists.gforge.inria.fr] On Behalf Of Nicolas Cellier [nicolas.cellier.aka.nice at gmail.com]
> Sent: Friday, April 08, 2011 1:14 PM
> To: Pharo-project at lists.gforge.inria.fr
> Subject: Re: [Pharo-project] Unexpected behavior of roundTo:
>
> Once more, Floats are inexact.
>    0.01 ~= 0.01s2
> The name #absPrintExactlyOn:base: is lying, it does not print exactly,
> but it prints the shortest decimal representation than will be rounded
> to the same Float when read back.
>
> To print it exactly, you need to use #printShowingDecimalPlaces: indeed.
> As every finite Float is a represented internally as a Fraction with a
> denominator being a power of 2, every finite Float has a decimal
> representation with a finite number of decimals digits (just multiply
> numerator and denominator with adequate power of 5, and you'll get the
> digits).
>
> So try:
> 0.01 printShowingDecimalPlaces: 59
> -> 0.01000000000000000020816681711721685132943093776702880859375
>
> You see that even if you try to execute the operation without rounding
> error, then convert it back to Float, you get the error:
>  (2.8011416510246336 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat
> ->  2.8000000000000003
>
> When you perform the #roundTo: operations in Float inexact arithmetic,
> you may accumulate more rounding errors, so the result may vary.
>
> If you want to round to an exact hundredth, then use exact arithmetic and try:
>   2.8011416510246336 roundTo: 0.01s2
>
> Hope it helps to consider Float for what they are, inexact but fast.
> Don't put too much expectations on them.
>
> Nicolas
>
> 2011/4/8 Hilaire Fernandes <hilaire.fernandes at gmail.com>:
>> It looks like a known issue:
>>
>> printShowingDecimalPlaces: placesDesired
>>        "This implementation avoids any rounding error caused by rounded or
>> roundTo: "
>>        ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
>>
>>
>>
>> Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
>>> 2.8011416510246336 roundTo: 0.01
>>>
>>> returns
>>>
>>>  2.8000000000000003
>>>
>>>
>>> Tested with 1.2
>>>
>>>
>>> Should I fill a ticket, I don't see anythings similar?
>>>
>>> Hilaire
>>>
>>
>>
>> --
>> Education 0.2 -- http://blog.ofset.org/hilaire
>>
>>
>>
>
>
>



More information about the Pharo-project mailing list