Hi Richard,

+1 to what was asked by Stef.
How hard is it to bring your knowledge, and existing implementation,
into a "proper" implementation of ScaledDecimal (or FixedPoint) in
Pharo?

Regards!

Esteban A. Maringolo

On Wed, Sep 2, 2020 at 12:12 PM Stéphane Ducasse
<stephane.duca...@inria.fr> wrote:
>
> 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> 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
>

Reply via email to