[Pharo-dev] summary of "float & fraction equality bug"

Florin Mateoc fmateoc at gmail.com
Fri Nov 10 17:04:34 EST 2017


On 11/10/2017 4:42 PM, Florin Mateoc wrote:
> On 11/10/2017 4:18 PM, Nicolas Cellier wrote:
>>
>>
>> 2017-11-10 20:58 GMT+01:00 Martin McClure <martin at hand2mouse.com <mailto:martin at hand2mouse.com>>:
>>
>>     On 11/10/2017 11:33 AM, raffaello.giulietti at lifeware.ch <mailto:raffaello.giulietti at lifeware.ch> wrote:
>>
>>         Doing only Fraction->Float conversions in mixed mode won't preserve = as
>>         an equivalence relation and won't enable a consistent ordering with <=,
>>         which probably most Smalltalkers consider important and enjoyable
>>         properties.
>>
>>     Good point. I agree that Float -> Fraction is the more desirable mode for implicit conversion, since it can
>>     always be done without changing the value.
>>
>>         Nicolas gave some convincing examples on why most
>>         programmers might want to rely on them.
>>
>>
>>         Also, as I mentioned, most Smalltalkers might prefer keeping away from
>>         the complex properties of Floats. Doing automatic, implicit
>>         Fraction->Float conversions behind the scenes only exacerbates the
>>         probability of encountering Floats and of having to deal with their
>>         weird and unfamiliar arithmetic.
>>
>>     One problem is that we make it easy to create Floats in source code (0.1), and we print Floats in a nice decimal
>>     format but by default print Fractions in their reduced fractional form. If we didn't do this, Smalltalkers might
>>     not be working with Floats in the first place, and if they did not have any Floats in their computation they
>>     would never run into an implicit conversion to *or* from Float.
>>
>>     As it is, if we were to uniformly do Float -> Fraction conversion on mixed-mode operations, we would get things like
>>
>>     (0.1 * (1/1)) printString                       -->
>>     '3602879701896397/36028797018963968'
>>
>>     Not incredibly friendly.
>>
>>
>> For those not practicing the litote: definitely a no go.
>>
>>
>>     Regards,
>>     -Martin
>>
>>
>> At the risk of repeating myself, unique choice for all operations is a nice to have but not a goal per se.
>>
>> I mostly agree with Florin: having 0.1 representing a decimal rather than a Float might be a better path meeting more
>> expectations.
>>
>> But thinking that it will magically eradicate the problems is a myth.
>>
>> Shall precision be limited or shall we use ScaledDecimals ?
>>
>> With limited precision, we'll be back to having several Fraction converting to same LimitedDecimal, so it won't solve
>> anything wrt original problem.
>
> I don't think people have problems with understanding limited precision. We do know that when we write 3.14.. we did
> not write Pi.
> As long as it does not contradict the intuition that we developed early on (and that's the problem with the binary
> representation of floats, not that it is limited)...
>
>> With illimted precision we'll have the bad property that what we print does not re-interpret to the same
>> ScaledDecimal (0.1s / 0.3s), but that's a detail.
>> The worse thing is that long chain of operations will tend to produce monster numerators denominators.
>> And we will all have long chain when resizing a morph with proportional layout in scalable graphics.
>
> But I did not propose to drop floats, just to change the visible representation of literals: 0.1 would mean a
> ScaledDecimal literal and 0.1f would mean a float literal. The extra "f" would be a constant reminder that something
> special is going on (the dangers of interpreting the literal as an exact representation in base 10).
>

And there would still be a lot of places where we would continue to judiciously use floats, such as in morphic. Just
like today people don't use fractions when they don't need their extra precision - ah, who am I kidding?
There are a lot of developers out there who would go to great lengths to save an extra keystroke. :)
Well, I think it could be made to work (e.g. one of the low-hanging fixes would be that multiplication of scaledDecimals
would add their scales) and it would complement nicely Smalltalk's seamless and intuitive largeIntegers - just like
largeIntegers liberate us from the tyranny of the hardware representation for integers, we should also not be prisoners
to the hardware representation of floats.

>> We will then have to insert rounding operations manually for mitigating the problem, and somehow reinvent a more
>> inconvenient Float...
>
> I don't think we would have to reinvent Float - this one would stay exactly the same (other than printing the extra f
> (or d)).
> But I agree that you raise an important point with precision/scale. We would indeed need to make ScaledDecimal more
> complicated.
> Because today 0.1s * 0.1s is printed as 0.0s1, even though 0.1s * 0.1s = (1/100) evaluates to true, which is nice.
>
>> It's boring to allways play the role of Cassandra, but why do you think that Scheme and Lisp did not choose that path?
>>
> Oh. come on, if Scheme and Lisp did it all already, why are we all here? :)
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20171110/13e881a8/attachment-0002.html>


More information about the Pharo-dev mailing list