Richard we are really interested in improving Pharo on that aspect. Now I’m really not good with such domain. Can you send us some code and tests?
S. > On 2 Sep 2020, at 12:31, Richard O'Keefe <rao...@gmail.com> wrote: > > The behaviour of ScaledDecimal in Squeak and Pharo is > - different from what the ANSI Smalltalk standard says > - different from what other Smalltalks do (not that they agree) > - completely different from decimal arithmetic in COBOL, PL/I, or SQL > - seriously confusing. > > What you EXPECT is an exact rational number that is equal to an > integer divided by a power of 10, so that the printed > representation faithfully represents the value with no error. > What you GET in Pharo is a rational number that PRINTS with > a given number of decimal places but that is all. > > Thus we expect that > x := 10/3 asScaledDecimal: 2. > x asString ==> '3.33s2' > y := x+x+x. > y asString ==> '9.99s2' > But no, y asString => '10.00s2'. > > Here's what the comment in the VW class FixedPoint says: > "There are two possible ways to express FixedPoint numbers. One is as a > scaled Integer, but the problem here is that you can lose precision during > intermediate calculations. For example, a property that seems useful is that > the calculation (1.000 / 7 * 7) should give you back the number 1.000. > > For this reason, we have adopted an alternative representation, which is a > slight variation on Fraction. The number is expressed as the ratio of a > numerator to a denominator, with the addition of a precision that is used for > printing and for rounding. The number is not usually rounded off to its > scale, but if an intermediate result must be rounded to its scale before > being used, the messages #roundedToScale and #truncatedToScale may be used." > > The last sentence in the first paragraph is one I cannot agree with. > If I want a calculation where (1/7 * 7) gives me back 1, then I use > exact Fractions. If I am using ScaledDecimal, it is because I *want* > fixed point decimal numbers, with the properties appropriate to fixed > point decimal numbers. Wanting something that I could use to talk to > databases like MariaDB I found that I had to write my own FixedPoint > class, only to find that VW called ScaledDecimal FixedPoint. *Sigh*. > > Unless and until the current ScaledDecimal is ripped out and buried > in an unmarked grave at a crossroad with a stake through its heart, > you may wish to add VW-compatibility methods > > roundedToScale > |t| > t := 10 raisedToInteger: scale. > ^(numerator * t / denominator) rounded / t asScaledDecimal: scale > > truncatedToScale > |t| > t := 10 raisedToInteger: scale. > ^(numerator * t / denominator) truncated / t asScaledDecimal: scale > > and then use > > aScaledDecimal roundedToScale = anotherOne roundedToScale > > Note that the ANSI standard, which was agreed to by a whole bunch of > Smalltalk experts, says "A <scaledDecimal> converted to a <Fraction> > will be a fraction having the same numeric value but having an integer > numerator and a denominator which is ten raised to > the power of the <scaledDecimal>’s scale factor." > Try "(10.00s2 / 3) asFraction" in your Smalltalk, and if the > result has a denominator of 3, SOMEONE stuffed up. > > > > > On Tue, 1 Sep 2020 at 16:08, Esteban Maringolo <emaring...@gmail.com > <mailto:emaring...@gmail.com>> wrote: > Hi, > > I was doing some basic calculations based on a formula, and I wanted > to convert the result to a scaled decimal in order to avoid having > these "loose" decimals in 10th position or something similar. > > So I did the following: > 82 - (2 * 35.9) - (0 / 2) * (113/121) asScaledDecimal: 1 -> 9.5s1 > > But When I do this in a test: > (82 - (2 * 35.9) - (0 / 2) * (113/121) asScaledDecimal: 1) = 9.5s1 > > It fails because the comparison returns false. > > I guess this is the proper behavior, but I'd expected that the > conversion from a Float to a scaled decimal would have eliminated the > extra precision from the formula. > > I can do a roundTo: 0.1 before converting, but I'd like to know what > would be the proper way of dealing with this. > > Thanks! > > Esteban A. Maringolo > -------------------------------------------- Stéphane Ducasse http://stephane.ducasse.free.fr / http://www.pharo.org 03 59 35 87 52 Assistant: Aurore Dalle FAX 03 59 57 78 50 TEL 03 59 35 86 16 S. Ducasse - Inria 40, avenue Halley, Parc Scientifique de la Haute Borne, Bât.A, Park Plaza Villeneuve d'Ascq 59650 France