2012/9/7 Denis Kudriashov <dionisiydk@gmail.com>:
Thank's for your answer. Only one of your solutions works: (146.015 asMinimalDecimalFraction roundTo: 1/100) asFloat => 146.02
Others not works:
(146.015 * 100.0) rounded / 100.0 => 146.01 (146.015 asFraction roundTo: 1/100) asFloat => 146.01
That's expected, '146.015' asFloat is already smaller than (146015/1000) so if you convert the float value asFraction or asScaledDecimal, it's too late, rounding error is already there. You have to use Fraction, ScaledDecimal or FixedDecimal of Chris right from the beginning, and don't use Float at all.
2012/9/7 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>
Hi Denis, If you decompose the operation performed by round:
(146.015 / 0.01) rounded * 0.01
'146.015' asFloat is inexact '0.01' asFloat is inexact / 0.01 operation is inexact '0.01' asFloat is inexact (again) * 0.01 operation is inexact
That means cumulating 5 inexact operations, how do you say "jouer à la roulette russe"?
Pharo guys did propose a better scheme
(146.015 * 100.0) rounded / 100.0
Since '100.0' asFloat is exact, that leave only 2 inexact operations and works much better (and we know the last one rounds exactly).
But if (146.015 asFraction < 146.015s3) then you still have a problem with inexactness of original value.
I see two solutions for this root problem: - don't use Float, but Fraction or ScaledDecimals - use a trick, asMinimalDecimalFraction which I proposed in http://code.google.com/p/pharo/issues/detail?id=4957 that will convert ('146.015' asFloat) to the exact fraction that is printed 146015/1000...
(x asMinimalDecimalFraction roundTo: 1/100) asFloat would thus be close to your requirements...
Nicolas
2012/9/7 Denis Kudriashov <dionisiydk@gmail.com>:
Hello.
I know there are many similar questions.
Maybe somebody give me fast answer.
146.015 roundTo: 0.01 => 146.01
I guess internal representation of 146.015 is something like 146.014999999999... That's why rounding result is 146.01
But how I can round arbitrary float my math root? How to fix my example to get 146.02?
Best regards, Denis