Hey Martin... I agree on the confusion.
> I still recommend not rounding the number itself, but
rounding the printing of the number
Yes.
If "rounding" had well specified behavior that was at least somewhat
reasonable (e.g. return the closest floating point value and round to
even if tied), I'd accept floating point results that don't print
"pretty" in base 10. That's the way things are, there's no point in
pretending IEEE-754 is not base 2.
If "rounding" is being done in place of "printing", or obtaining a
"string representation", I think that won't work as expected because 0.1
not representable etc.
For "printing", the algorithms were Dragon4 and Grisu3 last time I checked.
For "floating point that works nice in base 10", there's IEEE-854. For
those unfamiliar with the spec, it's been implemented in non-exotic
hardware already.
> you did proof that, as you said "1.2000000000000002 *is* the correct
answer for 1.19 roundTo: 0.1.".
As a suggestion for these types of problems, try iterating over a
floating point bit range converting each to a true fraction and see
which one is closest?
> testIfCompletelyBroken [doesn't round to even]
I'd agree rounding to even would be better.
Guillermo,
> And also: I'd argue that you NEVER EVER want to use simple Floats for
financial applications
Define "financial" applications? In the risk management world, tying
down that last $1 difference will likely cost more electricity (and way
more time) than the $1 is worth.
John,
> While ANSI says that the numbers should be converted using the
default conversion table, all of the Smalltalk’s that I’ve tried don’t
follow that. I’ve tried Dolphin, VW, Pharo, & VAST, and all return
fractions. I prefer this behavior over the ANSI behavior.
I agree that ANSI doesn't always make the best sense. If it were up to
me, I'd follow the relevant standard to the letter. That's more
important than providing a custom interpretation of an interoperability
mechanism just for Smalltalk (or a particular dialect) by default.
Nicolas,
> printShowingDecimalPlaces:
That's quite a long selector. Has anyone considered an approach along
the lines of this?
1.2345 %f #'3.2' => ' 1.23'
1.2345 %f #'03.2' => '001.23'
A reminder: calling printf() via FFI is undefined behavior.
Andres.
On 10/26/16 23:31 , Martin McClure wrote:
On 10/26/2016 08:27 AM, stepharo wrote:
So what is the definition of printShowingMaxDecimalDigit:?
I have the impression that there is a confusion between the rounding a
number and the printing of his value in a given format.
Yes, I see quite a bit of confusion in this thread about that.
we can deprecate roundTo: if necessary.
I think roundTo: is OK. #round: is not, and should be deprecated (at
least for Floats). For Floats, the idea of rounding to a specific number
of decimal digits is a fantasy. Here's why: Floats cannot exactly
represent most common decimal fractions. For example:
0.1 -- not representable
0.2 -- not representable
0.3 -- not representable
0.4 -- not representable
0.5 -- hey, representable!
0.6 -- not representable
0.7 -- not representable
0.8 -- not representable
0.9 -- not representable
1.0 -- representable.
*Printing* a Float to a specific rounded decimal format is a sensible
idea, and should be encouraged. But trying for a "rounded Float"
*number* just can't be done exactly (except by converting to a Fraction).
Fractions can be rounded to exact decimal fractions, so something like
"myFraction roundTo: 1/100" makes sense. But the current implementation
of round: on Fraction that converts to a Float just gets you the misery
detailed above.
On 10/26/2016 01:00 PM, Nicolas Cellier wrote:
I've put a single slice in the inbox for the 3 issues because they all
are related.
See slice comment:
For Float, implement guard to prevent overflow (15471), and use exact
representation for intermediate results (asFraction) so as to avoid
double rounding problems (15473)
The double rounding problem is not the fundamental problem, the
fundamental problem is that what is desired does not exist, because
Floats cannot exactly represent most decimal fractions. So this can't
really fix it.
For Fraction (15472), choose an exact representation for result rather
than Float. This is because such method is particularly usefull for
financial/monetary applications.
Yes. Fraction or ScaledDecimal. Not Floats, unless the developer
understands the needs of the financial world and the limitations of
Floats very well.
Regards,
-Martin