Bug in Floats?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug in Floats?

vaidasd
1245 *  0.01 evaluates to 12.45 in Squeak 4.3, but it is
12.450000000000001 in later versions.
regatds,
Vaidotas

Reply | Threaded
Open this post in threaded view
|

Re: Bug in Floats?

Chris Muller-3
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 <[hidden email]> wrote:
> 1245 *  0.01 evaluates to 12.45 in Squeak 4.3, but it is
> 12.450000000000001 in later versions.
> regatds,
> Vaidotas
>

Reply | Threaded
Open this post in threaded view
|

Re: Bug in Floats?

Nicolas Cellier

2014-04-09 17:53 GMT+02:00 Chris Muller <[hidden email]>:
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 <[hidden email]> 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.
 



Reply | Threaded
Open this post in threaded view
|

Re: Bug in Floats?

Nicolas Cellier



2014-04-09 20:16 GMT+02:00 Nicolas Cellier <[hidden email]>:

2014-04-09 17:53 GMT+02:00 Chris Muller <[hidden email]>:

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 <[hidden email]> 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'


Reply | Threaded
Open this post in threaded view
|

Re: Bug in Floats?

Nicolas Cellier

2014-04-09 22:23 GMT+02:00 Nicolas Cellier <[hidden email]>:



2014-04-09 20:16 GMT+02:00 Nicolas Cellier <[hidden email]>:


2014-04-09 17:53 GMT+02:00 Chris Muller <[hidden email]>:

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 <[hidden email]> 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).


Reply | Threaded
Open this post in threaded view
|

Re: Bug in Floats?

vaidasd
In reply to this post by Nicolas Cellier
Thank you for clarification.
Vaidotas

On Wed, Apr 9, 2014 at 9:16 PM, Nicolas Cellier
<[hidden email]> wrote:

>
> 2014-04-09 17:53 GMT+02:00 Chris Muller <[hidden email]>:
>
>> 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 <[hidden email]>
>> 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.
>
>
>
>
>