[squeak-dev] Bug in Floats?

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Apr 9 20:27:00 UTC 2014


2014-04-09 22:23 GMT+02:00 Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com>:

>
>
>
> 2014-04-09 20:16 GMT+02:00 Nicolas Cellier <
> nicolas.cellier.aka.nice at gmail.com>:
>
>
>> 2014-04-09 17:53 GMT+02:00 Chris Muller <asqueaker at gmail.com>:
>>
>> It's just a different printOn: method.  The new one shows the "truth".
>>>  You must now use one of the print formatting methods to display
>>> pretty Floats.
>>>
>>> On Wed, Apr 9, 2014 at 10:07 AM, Vaidotas Didžbalis <vaidasd at gmail.com>
>>> wrote:
>>> > 1245 *  0.01 evaluates to 12.45 in Squeak 4.3, but it is
>>> > 12.450000000000001 in later versions.
>>> > regatds,
>>> > Vaidotas
>>> >
>>>
>>>
>> Every two different Float shall have a different printString:
>> (12.45) = (1245*0.01) -> false.
>> So...
>>
>> The printString shall be the shortest decimal that rounds to the same
>> float.
>> It's hard to demonstrate with a simple snippet, but you can check that we
>> are very close yet:
>> ((Fraction readFrom: '12.450000000000001') - (1245*0.01) asTrueFraction)
>> / (1245*0.01) ulp.
>> ((Fraction readFrom: '12.45') - (1245*0.01) asTrueFraction) / (1245*0.01)
>> ulp.
>>
>>
>>
> Maybe some other usefull expressions:
>
> ((1245*0.01) asTrueFraction printShowingMaxDecimalPlaces: Float precision
> - Float emin + 1)
> -> '12.4500000000000010658141036401502788066864013671875'
>
> "Find least number of decimals necessary for converting back to the same
> float"
> ((1 to: Float precision - Float emin + 1) detect: [:i | ((1245*0.01)
> asTrueFraction roundTo: (10 raisedTo: i) reciprocal) asFloat = (1245*0.01)])
> -> 15
>
> "A variant..."
> ((1 to: Float precision - Float emin + 1) detect: [:i | (((1245*0.01)
> asTrueFraction roundTo: (10 raisedTo: i) reciprocal) - (1245*0.01)
> asTrueFraction) abs <= ((1245*0.01) ulp / 2)])
> -> 15
>
> ((1245*0.01) asTrueFraction printShowingDecimalPlaces: 15)
>  '12.450000000000001'
>

Ah, and of course, don't forget those ones:

(12.45 asTrueFraction printShowingMaxDecimalPlaces: Float precision - Float
emin + 1)
-> '12.449999999999999289457264239899814128875732421875'

so:

12.45s2 = 12.45
-> false

Float are represented in binary internally, not decimals, so every
conversion binary <-> decimal might be inexact (and most often is).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20140409/1f0d2c57/attachment.htm


More information about the Squeak-dev mailing list