Inconsistent number comparison?

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

Inconsistent number comparison?

Sean P. DeNigris
Administrator
Why does "1 = 1.0" but "273.15 ~= (5463/20)"? You must send #asFloat to the fraction to answer true...
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

Nicolas Cellier
Because there are infinitely many fractions that are approximately equal to 273.15 (the float).
and because we want to have this property a=b & (a=c) ==> (b=c).

Nicolas

2015-05-27 5:00 GMT+02:00 Sean P. DeNigris <[hidden email]>:
Why does "1 = 1.0" but "273.15 ~= (5463/20)"? You must send #asFloat to the
fraction to answer true...



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Inconsistent-number-comparison-tp4828795.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

Nicolas Cellier


2015-05-27 11:00 GMT+02:00 Nicolas Cellier <[hidden email]>:
Because there are infinitely many fractions that are approximately equal to 273.15 (the float).
and because we want to have this property a=b & (a=c) ==> (b=c).

Nicolas


Also because it's good to know that 1/10 ~= 0.1

But maybe the question is why 1=1.0 ?
Because we want to have the numbers sortable... Would 1<1.0 or 1>1.0 be better?
If you can't compare, then be prepared to change hierarchy (what's the sole purpose of Magnitude) and also rewrite a lot of code...

Nicolas
 
2015-05-27 5:00 GMT+02:00 Sean P. DeNigris <[hidden email]>:
Why does "1 = 1.0" but "273.15 ~= (5463/20)"? You must send #asFloat to the
fraction to answer true...



-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Inconsistent-number-comparison-tp4828795.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.



Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

Sean P. DeNigris
Administrator
In reply to this post by Nicolas Cellier
Nicolas Cellier wrote
we want to have this property a=b & (a=c) ==> (b=c).
If IUC it sounds more inconsistent because
  (5463/20) = (10926/40) "true"
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

Sean P. DeNigris
Administrator
In reply to this post by Nicolas Cellier
Nicolas Cellier wrote
Also because it's good to know that 1/10 ~= 0.1
Why? It's an implementation detail. #= unlike #== is IIUC supposed to be logical to the domain, and math doesn't make any distinction about how bits are stored ;)
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

Nicolas Cellier


2015-05-27 14:24 GMT+02:00 Sean P. DeNigris <[hidden email]>:
Nicolas Cellier wrote
> Also because it's good to know that 1/10 ~= 0.1

Why? It's an implementation detail. #= unlike #== is IIUC supposed to be
logical to the domain, and math doesn't make any distinction about how bits
are stored ;)



Nope, it's more than a detail.
It's what every engineer should know about floating point.
If you think float == real number then you'll be screwed by many unexpected behavior, like why 0.1+0.1+0.1 ~= 0.3 etc...
So you have to somehow unlearn what you were teached in math, because it's simply not true with float.
And the faster you get this feedback, the better.

 

-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Inconsistent-number-comparison-tp4828795p4828892.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

Nicolas Cellier
In reply to this post by Sean P. DeNigris


2015-05-27 14:15 GMT+02:00 Sean P. DeNigris <[hidden email]>:
Nicolas Cellier wrote
> we want to have this property a=b & (a=c) ==> (b=c).

If IUC it sounds more inconsistent because
  (5463/20) = (10926/40) "true"



What is less consistent is that these fractions are all different:

fractions := (101 to: 200) collect:  [:n | 1<<n+1/(1<<n)].
[fractions asSet size = 100] assert.

But they are all "equal" to the same float:

[fractions allSatisfy: [:f | f asFloat = 1.0]] assert.
[(fractions collect: #asFloat as: Set) size = 1] assert.

Don't you see a problem now?


-----
Cheers,
Sean
--
View this message in context: http://forum.world.st/Inconsistent-number-comparison-tp4828795p4828890.html
Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

Florin Mateoc
In reply to this post by Nicolas Cellier
On 5/27/2015 1:29 PM, Nicolas Cellier wrote:


2015-05-27 14:24 GMT+02:00 Sean P. DeNigris <[hidden email]>:
Nicolas Cellier wrote
> Also because it's good to know that 1/10 ~= 0.1

Why? It's an implementation detail. #= unlike #== is IIUC supposed to be
logical to the domain, and math doesn't make any distinction about how bits
are stored ;)



Nope, it's more than a detail.
It's what every engineer should know about floating point.
If you think float == real number then you'll be screwed by many unexpected behavior, like why 0.1+0.1+0.1 ~= 0.3 etc...

Totally agree until now :)

So you have to somehow unlearn what you were teached in math, because it's simply not true with float.

I think this is not well formulated and it might actually deepen the misunderstanding. There is no math to be unlearned. There is just some extra info that has to be remembered about computers.
I don't think anybody was ever taught in math class that 0.33 equals 1/3. Not even that 0.3333333333333333 equals 1/3. Not even in the US (although there is a state where a guy introduced a law to change the value of Pi to 3, to make things simpler :)).

Here we have the same situation. For these particular floats, their literal value, as expressed in base 10 digits (which is what we do when we input them in source code), has no exact representation (in binary, which is how they are actually compiled/stored), so from the very start these floats are just an approximation. Perhaps the compiler should warn people every time they write such a literal. This would be easy to do and I think it would save people a lot of heartburn.

It is very revealing to look at 0.1 asTrueFraction or at 273.15 asTrueFraction , and then it will become obvious why these floats are not equal with those fractions.
Whereas if you take the very same base 10 literals, but not in float format but as scaledDecimals, the comparisons evaluate to true, as they should:
1/10 = 0.1s and 273.15s = (5463/20).

Florin
Reply | Threaded
Open this post in threaded view
|

Re: Inconsistent number comparison?

stepharo
In reply to this post by Sean P. DeNigris
Read fun with numbers in deep into pharo :)

Le 27/5/15 05:00, Sean P. DeNigris a écrit :

> Why does "1 = 1.0" but "273.15 ~= (5463/20)"? You must send #asFloat to the
> fraction to answer true...
>
>
>
> -----
> Cheers,
> Sean
> --
> View this message in context: http://forum.world.st/Inconsistent-number-comparison-tp4828795.html
> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>
>