Hi Nocolas,
Thanks for the review. I have not actually used this for arithmetic yet, I added that in a couple of hours before publishing this. Previously this has been used to represent the decimal values that I needed to use to load into a database using a fixed length representation. This need influenced my design quite a bit. However, without arithmetic, it isn't very useful for many other people (or myself going forward).
As to your points;
(-53/10 asFixedDecimal: 2) fractionPart.
- why maintaining so many forms in parallel ?
Not bug-proof, you happen to update one form not the other...
sign is not handled in part1 nor part2
- negated should create a new instance
rather than modifying the number in place
- FixedDecimals does not implement hash,
therefore cannot be stored in a Dictionary.
Particularly, cannot be stored in a workspace variable.
I suggest hash ^self asFraction hash
- likewise, implement all subclassResponsibility
( 5/3) * (5/3 asFixedDecimal: 2).
( 2.0s1) * (5/3 asFixedDecimal: 2).
(5/3 asFixedDecimal: 2) reciprocal.
- coercion depends on receiver:
| a b |
a := (53/10 asFixedDecimal: 2).
b := 5.3.
{ (a+b) class.
(b+a) class. } "is {FixedDecimal . Float}"
- maybe add another rounding mode in arithmetic (to nearest even...)
- create a specific notation for transparent read/write, like 5.30f
(requires some easy support in Number class>>readFrom: or NumberParser)
From algebraic point of view, the main concern is that some numbers
might not have any reciprocal...
Unless the reciprocal is a Fraction, and arithmetic op coerce to Fraction...
But, eh, this is just the case of Float:
| f |
f := (8872240531573379/9007199254740992) asFloat.
f * f reciprocal - 1