[squeak-dev] The joys (or not) of floating point numbers

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Tue Mar 26 19:40:19 UTC 2013


2013/3/26 Louis LaBrunda <Lou at keystone-software.com>:
> On Tue, 26 Mar 2013 18:59:12 +0100, Nicolas Cellier
> <nicolas.cellier.aka.nice at gmail.com> wrote:
>
>>2013/3/26 Louis LaBrunda <Lou at keystone-software.com>:
>>> On Tue, 26 Mar 2013 18:32:31 +0100, Stéphane Rollandin
>>> <lecteur at zogotounga.net> wrote:
>>>
>>>>> Example (0.995 round: 2) -> 1.00 though 0.995 < (995/1000) so it
>>>>> should round to 0.99.
>>>>
>>>>.. and I just noticed that
>>>>
>>>>       0.995 printShowingDecimalPlaces: 2   ==>  '1.00'
>>>>
>>>>Do we have a method returning the correct value ?
>>>
>>> That looks right to me, because 0.995 was rounded up.
>>>
>>> Lou
>>
>>No it's not, because 0.995 < 0.995s3 so it should be rounded down.
>>In a recent trunk image, print is OK:
>>(0.995 printShowingDecimalPlaces: 2) ->  '0.99'
>
> In VA Smalltalk:
>
> 0.995 = 0.995s3 => true
> 0.995 < 0.995s3 => false
>

This is a default st80 behavior which converts minimumGenerality
number to maximumGenerality.
Maybe some of these conventions are hardwired in VM, I don't know, but
in other dialects it's handled at image side.

The idea was this one: if you perform an operation between an inexact
value and an exact value, the result is inexact.
So Float + * / - Integer,Fraction,ScaledDecimal will result into a Float.
Thus Float got a higher generality.

The idea behind Squeak change is that every Float has an exact value
(asTrueFraction).
Since we have only two possible answers true/false for comparison, and
no maybe or dontKnow, it makes sense to compare the exact value.
This reduces the number of paradoxal equalities

| a b c |
a := 1 << Float precision.
b := a + 1.
c := a asFloat.
{
c = b.
c = a.
a = b.
}

In VW and VA, the first two are true, the last is false, which
suggests that = is not an equivalence relation.
In Squeak, only the second one is true.

Same with inequalities, we expect (a < b) & (a = c) ==> (c < b) etc...
This is still true in Squeak, not in VA/VW/st80.
I think gst and Dolphin and maybe stx adopted Squeak behavior (to be confirmed).


> I think in VA Smalltalk there is some VM magic going on that makes the
> above work the way it does.  The #= and #< of Float are implemented in a
> primitive.  I guess when converting the '0.995' string to a float a little
> is lost and that would make it less than 0.995s3 but there is a lot of code
> floating around (sorry about the puns) to make floats look better.  In that
> case I would think people would want (0.995 printShowingDecimalPlaces: 2)
> to show '1.00' and not '0.99'.
>

No, people should not rely on such behavior with Floats, because
sooner than later they will be bitten.
We cannot cheat very long with this kind of assumptions.
My POV is that it is better to educate about false expectations with
Float, and that's the main benefit of (1/10) ~= 0.1.

I would add that such print policy is not the behaviour of every other
language I know of.

printf( "%.2f",0.995)
-> 0.99

Because libm are carefully written nowdays and other languages
libraries are either built over libm or much more careful than
Smalltalk were (that mostly means more recent).

> Anyway, we should try not to use floats without a very, very good reason.
> Like we have to send them outside of Smalltalk or we really need the speed
> or decimals and fractions take up too much memory.  But then we must live
> with their inaccuracies and display mess.
>

Good advice, let's put those expectations on decimal fractions
(ScaledDecimal/FixedPoint) or general Fraction.

> I have an untested theory that fractions can be close in speed to floats
> because divisions (that are expensive) can be pushed to the end of a
> computation because with fractions they are multiplies.
>
> Lou

Why not, but huge numerators and denominators are not cheap compared
to Float operations.
OK reducing the fraction is the expensive part, but how does the cost
grow versus the length of operands?

Also some geometric operations are not even possible on Q (hypot) so
you might soon need AlgebraicNumber.
And Smalltalk is also about graphics and geometry.

Nicolas

> -----------------------------------------------------------
> Louis LaBrunda
> Keystone Software Corp.
> SkypeMe callto://PhotonDemon
> mailto:Lou at Keystone-Software.com http://www.Keystone-Software.com
>
>


More information about the Squeak-dev mailing list