[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