[squeak-dev] Decimals as fractions
K K Subbu
kksubbu.ml at gmail.com
Mon Apr 8 09:22:07 UTC 2019
On 07/04/19 7:46 PM, Nicolas Cellier wrote:
> Hi,
> Yes sure, that's a possibility.
> But that means changing well established Smalltalk syntax, and thus
> modify a huge library of source code...
I am not suggesting any changes to syntax (yet!). I was exploring an
idea of storing decimal numbers like '3.41' in a lossless form and
convert to float on demand (possibly cached). Internal format would be
totally transparent to the rest of the code. We already do these for
integers:
(1 / 1) class SmallInteger
(1 / 3) class Fraction
(3 / 1) class SmallInteger
> We currently have ScaledDecimal with 3.41s or 3.42s2 syntax.
> The problem with ScaledDecimal is that their printing is ambiguous: two
> different ScaledDecimal may print the same.
>
> {1.0s2 / 3.0s2. 0.33s2} collect: #printString.
> {1.0s2 / 3.0s2. 0.33s2} collect: #reciprocal.
Is Squeak 5.3alpha/64b/Linux, I get
{1.0s2 / 3.0s2. 0.33s2} collect: #reciprocal {3.00s2 . 3.03s2}.
But I get your point. For decimal numbers, using both denominator and
scale is an overkill. Printing can be handled by the existing
printFractionAs... . Reciprocal of a decimal number could become
imprecise operation, so we could fall back to Float when necessary.
With decimal numbers, we could print
0.25 reciprocal = 4
instead of the current
0.25 reciprocal = 4.166666666666667
> They just truncate in Squeak (and maybe round in Pharo, not even with
> banker rounding).
> This is because they are just Fraction in disguise, and that's their
> second problem: repeated computations could lead to monstruous fractions.
Like Pi you mean ;-). True. But, most real life scenarios involve only
small denominators like 2, 4, 5, 100 or 1000. Large denominators could
be handled through exceptions and reduction through gcd.
> That's why I'm interested in experiments: is their usage sustainable, or
> does it lead to explosion?
> It's very easy to experiment: introduce a new NumberParser subclass and
> connect it to Smalltalk Parser (via Scanner>>#xDigit).
> Then, carefully recompile some part of the system, and discover the
> vital source code where Float literals are required.
Thanks a ton for your encouraging words and the tips. I will give them a
try.
> Or we could have a DecimalFloat, a Floating point in base 10.
> https://en.wikipedia.org/wiki/Decimal_floating_point
> Maybe that's the practical universal Number that we are after?
> Of course, like the other kinds above, it would be emulated...
A variant - DecimalNumber. It would extend the idea of place values to
the negative axis without the drawbacks of IEEE754-2008.
I suppose it would be computationally inefficient compared to Float, but
definitely more accurate in common scenarios. I would love to see "0.25
reciprocal" evaluate to 4 ;-).
Regards .. Subbu
More information about the Squeak-dev
mailing list
|