[Pharo-project] About float: new chapter looking for reader and contributors

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Wed Apr 13 22:37:49 CEST 2011

Here is a small variation. It's not perfect, and most elements are
already in Stephane's text.
But maybe we can jump deeper in the first example that claims some explanations.

We can first explain that 0.1 will answer the Float nearest to (1/10).
Thanks to this important property, if we enter 0.1, it will be printed
0.1 and reinterpreted the same. A nice property to have!

However, what is fundamental is that this Float won't be equal to (1/10).
How is this so ? Hey we didn't learn that in school !
Well, Float have an internal representation in base 2, of the form
mantissa * (2 raisedTo: exponent).
There is no way to represent (1/10) in base 2 with a finite number of
bits...  (like illustrated with 1.3 example, #significandAsInteger,
#exponent, #ulp and such kind of messages...).
A rounding operation has to occur to make this number fit in Float
internal representation ( it might be good to tell that Pharo Float
follow the IEEE 754 double precision standard with a link to
http://en.wikipedia.org/wiki/IEEE_754-1985 . This standard governs the
way most FPU work on this planet).
This rounding operation introduce a rounding error, and thus we don't
get exactly (1/10).

To know the exact internal representation of 0.1 the Smalltalk way is
as usual to send a message: 0.1 asTrueFraction.
The same goes with 0.2, it's not equal to (2/10), check it with 0.2

So what goes on with this operation 0.1+0.2 ?
In fact you asked the system to perform following operation (0.1
asTrueFraction+0.2 asTrueFraction) asFloat.
(0.1 asTrueFraction+0.2 asTrueFraction) is an exact operation, but the
result again does not fit in Float internal representation:
(0.1 asTrueFraction+0.2 asTrueFraction) numerator highBit -> 54
(0.1 asTrueFraction+0.2 asTrueFraction) numerator lowBit -> 1
This means that 54 bits of mantissa are required to represent this
number. Float only have 53
Float precision -> 53
So converting it to aFloat requires another rounding operation, and
due to this rounding error,
(0.1 asTrueFraction+0.2 asTrueFraction) ~= (0.1 asTrueFraction+0.2
asTrueFraction) asFloat.
That's exactly how your IEEE-754 compliant FPU will work.

In the whole process, 3 rounding errors have been cumulated:
(1/10) asFloat -> 0.1 (the error is not yet visible, but it's here already)
(2/10) asFloat -> 0.2 (same)
(0.1 asTrueFraction+0.2 asTrueFraction) asFloat -> 0.30000000000000004

This is to be compared to 0.3, which has a single rounding error:
(3/10) asFloat -> 0.3

Due to these rounding errors, and the way they cumulate or annihilate,
both result might differ. And in this case, they differ.
This is a very important property of Float. Float are fast thanks to
hardware acceleration, and thanks to these rounding errors that keep
the number of significant bits from growing. But the counterpart is
that operations on Float are inexact. Due to this inexactness, it is
most often inadequate to rely on strict equality of Float, as this
very simple example illustrates. Instead, Float comparisons shall
better be tested with fuzzy tolerance.

Note that the nice thing with Pharo is that you immediately see that
(0.1+0.2) ~= 0.3 thanks to extraneous digits printed.
Pharo does not hide the horrible truth by shortening the printed
representation to 0.3 like some system do.
However, the decimal printed form does not show you the truth about
0.1 ~= (1/10). Inexactness is hidden. This is an implicit knowledge to
remember about Float, that you now learned with this lesson.

Remember, this is not a deficiency of Pharo. This is the way Float are
expected to work whatever the language.


2011/4/13 laurent laffont <laurent.laffont at gmail.com>:
> On Tue, Apr 12, 2011 at 6:07 PM, stephane ducasse <stephane.ducasse at free.fr>
> wrote:
>> Hi guys
>> I started to put in shape a chapter on floats based on the numerous
>> discussions we got over the years.
>> You can find it on github under the pharo by example book/Floats
> For me it's a good candidate for a ProfStef tutorial (text, evaluations,
> text, ...)
> Laurent
>> Stef

More information about the Pharo-project mailing list