eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'FixedPoint':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: FixedPoint


Inheritance:

   Object
   |
   +--Magnitude
      |
      +--ArithmeticValue
         |
         +--Number
            |
            +--Fraction
               |
               +--FixedPoint

Package:
stx:libbasic
Category:
Magnitude-Numbers
Version:
rev: 1.89 date: 2024/04/22 16:42:02
user: stefan
file: FixedPoint.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


These are named 'ScaledDecimals' in other systems and willl therefore be renamed
soon. For now, there is an alias and the class can be referred to by both names
'FixedPoint' and 'ScaledDecimal'.

This class implements infinite precision fixed-point numbers,
which internally hold exact (fractional) results, but print themself with
a limited number of digits after the decimal point (rounded). 

NOTICE:
    it seems that squeak prints these truncated,
    whereas ST/X prints them rounded.
    This behavior should probably be controllable by providing      
    a subclass (RoundedFixedPoint ?) which redefines the printOn: method.
    (it is now controlled by a classVar, which is of course not a thread-safe
    solution).

These can be used in computation, where rounding errors should not accumulate,
but only a limited precision is required for the final result.
(i.e. business applications)

It doesn't really do anything too interesting except creating instances, 
converting, and printing, since its superclass Fraction does all the work.

Test: 
    '123456789012345678901234567890.123456789' asScaledDecimal * 1000000000
    -> 123456789012345678901234567890123456789'

Notes: 1) The current implementation does not convert arbitrarily-based 
          String representations, which shouldn't be too much a problem 
          for financial types.

       2) the implementation is a hack - it has not been optimized for speed
          in particular.

Mixed mode arithmetic:
    fix op fix       -> fix, scale is max. of operands
    fix op fraction  -> fix; scale is fix's scale
    fix op integer   -> fix; scale is fix's scale
    fix op float     -> float


[aliases:]
    ScaledDecimal (ANSI)

copyright

This is public domain code, not covered by the ST/X copyright. Code is provided 'as is', as a goody, without any warranty. this comes from: Jan Steinman, Bytesmiths 2002 Parkside Court, West Linn, OR 97068-2767 USA, +1 503 657 7703 Friedlistrasse 19, CH-3006, Bern, Switzerland, +41 31 999 3946 this code was published in comp.lang.smalltalk; added here as an example ...

Class protocol:

Magnitude-Numbers
o  generality
return the generality value - see ArithmeticValue>>retry:coercing:

coercing & converting
o  coerce: aNumber
convert the argument aNumber into an instance of the receiver (class) and return it.

constants
o  e
e with roughly 26 valid digits...

Usage example(s):

     E := nil.
     self e
        -> 2.7182818284590452353602875
     wolfram:
           2.718281828459045235360287471352662497757247093699959574966...
     
     self e squared    
     self e reciprocal 
     1 / self e 
     self e * 1000000000000000000000000000000000000000000    

o  pi
pi with roughly 26 valid digits...

Usage example(s):

     Pi := nil.
     self pi
        -> 3.1415926535897932384626434
     wolfram:
        -> 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904...
     
     self pi squared    
     self pi reciprocal 
     1 / self pi 
     self pi * 1000000000000000000000000000000000000000000    

o  pi1000
pi with roughly 1000 valid digits...

Usage example(s):

     Pi_1000 := nil.
     
     self pi1000
        -> 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989
     wolfram:
        -> 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904...

     self pi1000 squared    
     self pi1000 reciprocal 

     (self pi1000 - self pi) asFloat

instance creation
o  numerator: n denominator: d
redefined to block the inherited instance creation method from fraction.
Raises an error - you must give a scale or provide a power-of-10 denominator

Usage example(s):

use #numerator:denominator:scale

Usage example(s):

^ self numerator:n denominator:d scale:(d log max:n log) ceiling

Usage example(s):

     self numerator:123 denominator:100    

o  numerator: n denominator: d scale: s
create and return a new fixedPoint instances with the given scale
(post decimal digits when printed). Will reduce if possible.

o  readFrom: aStringOrStream
return the next FixedPoint from the (character-)stream aStream.

NOTICE:
This behaves different from the default readFrom:, in returning
0 (instead of raising an error) in case no number can be read.
It is unclear, if this is the correct behavior (ST-80 does this)
- depending on the upcoming ANSI standard, this may change.

Usage example(s):

     FixedPoint readFrom:'.456'  
     FixedPoint readFrom:'123.456'  
     FixedPoint readFrom:'123.'  
     FixedPoint readFrom:'3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788'
     FixedPoint readFrom:(ReadStream on:'foobar')     
     FixedPoint readFrom:(ReadStream on:'foobar') onError:nil  
     FixedPoint readFrom:'0b1234' onError:nil  

     FixedPoint readFrom:'1'      
     FixedPoint readFrom:'2'      
     FixedPoint readFrom:'1.5'    

o  readFrom: aStringOrStream decimalPointCharacters: decimalPointCharacters onError: exceptionBlock
return an instance of me as described on the string or stream, aStringOrStream.
If an error occurs during conversion, return the result from evaluating exceptionBlock

Usage example(s):

     FixedPoint readFrom:'1.00'    
     FixedPoint readFrom:'100.00'    
     FixedPoint readFrom:'-100.00'    
     FixedPoint readFrom:'123.456'  
     FixedPoint readFrom:'123,456' decimalPointCharacters:',' 
     FixedPoint readFrom:'-123.456'     
     FixedPoint readFrom:'123'          
     FixedPoint readFrom:'-123' 
     FixedPoint readFrom:'-123.123s2' 
     FixedPoint readFrom:'-123.123' 

     FixedPoint readFrom:'-123.123s0' 
     Number readFrom:'0x1001' 
     Number readFrom:'0b0101' 
     Number readFrom:'0o0777' 

     -- notice the difference between readFromString and readFrom:
     
     FixedPoint readFromString:'-123.abcd' onError:[47.5]  
     FixedPoint readFromString:'-1a.bcd' onError:[47.5]  
     FixedPoint readFromString:'foot' onError:['bad fixedpoint'] 
     FixedPoint readFromString:'0b1234' onError:['bad fixedpoint'] 

     -- readFrom only reads what can be read, leaving the stream at the end:
     
     FixedPoint readFrom:'-123.abcd' onError:[47.5]  
     FixedPoint readFrom:'-1a.bcd' onError:[47.5] 
     FixedPoint readFrom:'foot' onError:['bad fixedpoint'] 
     FixedPoint readFrom:'0b1234' onError:['bad fixedpoint'] 

o  readFrom: aStringOrStream onError: exceptionBlock
return an instance of me as described on the string or stream, aStringOrStream.
If an error occurs during conversion, return the result from evaluating exceptionBlock

printing control
o  printTruncated
return the PrintTruncated flag, which controls printing.
See the description in the documentation for details

o  printTruncated: aBoolean
set the PrintTruncated flag, which controls printing.
See the description in the documentation for details

queries
o  exponentCharacter
return the character used to print between mantissa an exponent.
Also used by the scanner when reading numbers.


Instance protocol:

accessing
o  epsilon
return the epsilon
Assuming that the last digit is rounded, return half of that digits value.

Usage example(s):

     (2005 asScaledDecimal:-1) epsilon   => 5.0 
     (2005 asScaledDecimal:0) epsilon    => 0.5 
     (2 asScaledDecimal:0) epsilon   => 0.5 
     (2 asScaledDecimal:1) epsilon   => 0.05 
     (2 asScaledDecimal:2) epsilon   => 0.005
     (2 asScaledDecimal:4) epsilon   => 5e-05
     (2 asScaledDecimal:100) epsilon   
     (2 asScaledDecimal:1000) epsilon   

o  scale
return the number of places of significance that is carried by the receiver.

arithmetic
o  * aNumber
return the product of the receiver and the argument.
Redefined to care for the scale if the argument is another fixPoint number.
The result's scale is the maximum of the receiver's scale and the argument's scale.

Usage example(s):

     |a r|

     a := (ScaledDecimal fromString:'123.456').
     r := a * 5.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

Usage example(s):

     |a b r|

     a := (ScaledDecimal fromString:'123.456').
     b := (ScaledDecimal fromString:'1.10').
     r := a * b.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

Usage example(s):

     |a b r|

     a := (ScaledDecimal fromString:'123.456').
     b := (ScaledDecimal fromString:'-1.10').
     r := a * b.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

Usage example(s):

     |a b r|

     a := (ScaledDecimal fromString:'0.9999999').
     b := (ScaledDecimal fromString:'0.9999999').
     r := a * b.    
     Transcript show:'fixed (exact)  : '; showCR:r.    
     Transcript show:'fixed (scale2) : '; showCR:(r withScale:2).

     Transcript show:'float (inexact): '; showCR:(0.9999999 * 0.9999999).

Usage example(s):

     |a b r|

     a := 1.
     b := (ScaledDecimal fromString:'0.9999999').
     r := a * b.    
     Transcript show:'fixed (exact)  : '; showCR:r.    
     Transcript show:'fixed (scale2) : '; showCR:(r withScale:2).

     Transcript show:'float (inexact): '; showCR:(0.9999999 * 0.9999999).

Usage example(s):

     |a r|

     a := (ScaledDecimal fromString:'123.456').
     r := a * 5.0.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

Usage example(s):

     |a r|

     a := (ScaledDecimal fromString:'123.456').
     r := 5.0 * a.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

o  + aNumber
return the sum of the receiver and the argument, aNumber.
Redefined to care for the scale if the argument is another fixPoint number.
The result's scale will be the maximum of the receiver's and the argument's scale.

Usage example(s):

     ((1/3) asScaledDecimal:2) + 1    
     ((1/3) asScaledDecimal:2) + (1/3)

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'123.456').
     b := (ScaledDecimal fromString:'1.10').
     a + b

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.9999999').
     b := (ScaledDecimal fromString:'0.0000001').
     a + b                   

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.99').
     b := (ScaledDecimal fromString:'0.0000001').
     a + b                             

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.99').
     b := (ScaledDecimal fromString:'0.0000001').
     (a + b) withScale:2  

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.99').
     b := (ScaledDecimal fromString:'0.0000001').
     (a + b) withScale:1  

Usage example(s):

     |a b|

     a := 1.
     b := (ScaledDecimal fromString:'0.0000001').
     Transcript showCR:((a + b) withScale:1).
     Transcript showCR:(a + b)

o  - aNumber
return the difference of the receiver and the argument, aNumber.
Redefined to care for the scale if the argument is another fixPoint number.
The result's scale is the maximum of the receiver's scale and the argument's scale.

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'123.456').
     b := (ScaledDecimal fromString:'1.10').
     a - b     

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.9999999').
     b := (ScaledDecimal fromString:'0.0000009').
     a - b                   

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.99').
     b := (ScaledDecimal fromString:'0.0000001').
     a - b                          

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.99').
     b := (ScaledDecimal fromString:'0.0000001').
     (a - b) withScale:2  

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.99').
     b := (ScaledDecimal fromString:'0.0000001').
     (a - b) withScale:1  

Usage example(s):

     |a b|

     a := (ScaledDecimal fromString:'0.0000001').
     b := (ScaledDecimal fromString:'0.99').
     (a - b) withScale:2   

Usage example(s):

     |a b|

     a := 1.
     b := (ScaledDecimal fromString:'0.0000001').
     Transcript showCR:((a - b) withScale:1).
     Transcript showCR:(a - b)

o  / aNumber
return the quotient of the receiver and the argument, aNumber.
Redefined to care for the scale if the argument is another fixPoint number.
The result's scale is the maximum of the receiver's scale and the argument's scale.

Usage example(s):

     |a r|                     

     a := (ScaledDecimal fromString:'123.456').
     r := a / 5.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).
     Transcript showCR:(r withScale:9).

Usage example(s):

     |a b r|

     a := (ScaledDecimal fromString:'123.456').
     b := (ScaledDecimal fromString:'1.10').
     r := a / b.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

Usage example(s):

     |a b r|

     a := (ScaledDecimal fromString:'-123.456').
     b := (ScaledDecimal fromString:'-1.10').
     r := a / b.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

Usage example(s):

     |a b r|

     a := (ScaledDecimal fromString:'123.456').
     b := (ScaledDecimal fromString:'-1.10').
     r := a / b.    
     Transcript showCR:r.    
     Transcript showCR:(r withScale:2).

Usage example(s):

     |a b r|

     a := 1.
     b := (ScaledDecimal fromString:'0.9999999').
     r := a / b.    
     Transcript show:'fixed (exact)  : '; showCR:r.    
     Transcript show:'fixed (scale2) : '; showCR:(r withScale:2).

     Transcript show:'float (inexact): '; showCR:(1 / 0.9999999).

o  negated
redefined from Fraction to preserve scale

Usage example(s):

     0.050 asScaledDecimal:2                    -> 0.05
     (0.050 asScaledDecimal:2) negated          -> -0.05

     0.0 asScaledDecimal:2                      -> 0.00
     (0.0 asScaledDecimal:2) negated            -> 0.00

     0.054 asScaledDecimal:2                    -> 0.05
     (0.054 asScaledDecimal:2) negated          -> -0.05
     (0.054 asScaledDecimal:2) negated asFloat  -> -0.054

o  reciprocal
redefined from Fraction to preserve scale

Usage example(s):

     0.050 asScaledDecimal:2                 -> 0.05
     (0.050 asScaledDecimal:2) reciprocal    -> 20.00

     0.054 asScaledDecimal:2                 -> 0.05
     (0.054 asScaledDecimal:2) reciprocal    -> 18.52

coercing & converting
o  asFixedPoint
marked as obsolete by exept MBP at 18-09-2021

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  asFixedPoint: newScale
marked as obsolete by exept MBP at 18-09-2021

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  asFraction
return the receiver as a fraction

Usage example(s):

     (ScaledDecimal fromString:'0.2')           
     (ScaledDecimal fromString:'0.2') asFraction
     (ScaledDecimal fromString:'0.2') asFloat
     (ScaledDecimal fromString:'0.2') asShortFloat
     (ScaledDecimal fromString:'0.2') asInteger

o  asIntegerIfPossible
if the receiver can be represented as an integer without loosing precision,
return that integer. Otherwise, return the receiver.
Useful for printing / string conversion

Usage example(s):

     1.2345s3 asIntegerIfPossible
     12.345s3 asIntegerIfPossible
     123.45s3 asIntegerIfPossible
     1234.5s3 asIntegerIfPossible
     12345.0s3 asIntegerIfPossible
     12345s3 asIntegerIfPossible

     1.2345s3 asInteger

o  asScaledDecimal
return the receiver as a scaledDecimal number
- that's the receiver itself

o  asScaledDecimal: newScale
return a scaledDecimal with the same value as the receiver,
and newScale number of valid decimal digits

Usage example(s):

     '12345.12345' asScaledDecimal:2   
     (ScaledDecimal fromString:'12345.12345') asScaledDecimal:2 

     ((ScaledDecimal fromString:'0.33333333')
      + 
      (ScaledDecimal fromString:'0.33333333')
     ) asScaledDecimal:2   

o  coerce: aNumber
convert the argument aNumber into an instance of the receiver's class and return it.

o  generality
return the generality value - see ArithmeticValue>>retry:coercing:

double dispatching
o  differenceFromFraction: aFraction
sent when a fraction is asked to subtract the receiver.
The result has my scale.
Redefined here to preserve the receiver's scale.

o  differenceFromInteger: anInteger
sent when an integer does not know how to subtract the receiver.
The result has my scale.
Redefined here to preserve the receiver's scale.

o  differenceFromScaledDecimal: aScaledDecimal
sent when a fixedPoint is asked to subtract the receiver.
The result has the higher scale of the two operands.
Redefined here to compute the scale.

o  productFromFraction: aFraction
sent when a fraction is asked to multiply the receiver.
The result has my scale.
Redefined here to preserve the receiver's scale.

o  productFromInteger: anInteger
sent when an integer does not know how to multiply the receiver.
Redefined here to preserve the receiver's scale.

o  productFromScaledDecimal: aScaledDecimal
sent when a fixedPoint is asked to multiply the receiver.
The result has the higher scale of the two operands.
Redefined here to compute the scale.

o  quotientFromFraction: aFraction
Return the quotient of the argument, aFraction and the receiver.
Sent when aFraction does not know how to divide by the receiver.
Redefined here to preserve the receiver's scale.

o  quotientFromInteger: anInteger
Return the quotient of the argument, anInteger and the receiver.
Sent when anInteger does not know how to divide by the receiver.
Redefined here to preserve the receiver's scale.

o  quotientFromScaledDecimal: aScaledDecimal
sent when a fixedPoint is asked to divide by the receiver.
The result has the higher scale of the two operands.
Redefined here to compute the scale.

o  sumFromFraction: aFraction
sent when a fraction is asked to add the receiver.
The result has my scale.
Redefined here to preserve the receiver's scale.

o  sumFromInteger: anInteger
sent when an integer does not know how to add the receiver.
The result has my scale.
Redefined here to preserve the receiver's scale.

o  sumFromScaledDecimal: aScaledDecimal
sent when a fixedPoint is asked to add by the receiver.
The result has the higher scale of the two operands.
Redefined here to compute the scale.

inspecting
o  classNameShownInInspector
( an extension from the stx:libtool package )

mathematical functions
o  sqrt
compute the square root, using the Newton method.
The approximated return value has an error less than
the receiver's last digit, as specified in the scale.

Usage example(s):

     (2 asScaledDecimal:4) sqrt     
     (2 asScaledDecimal:100) sqrt   
     (2 asScaledDecimal:1000) sqrt   
     (10 asScaledDecimal:100) sqrt   
     (100 asScaledDecimal:100) sqrt   

     (5 asScaledDecimal:10) sqrt   

printing & storing
o  printDecimalOn: aStream roundToScale: roundToScale truncateToScale: truncateToScale
common helper for printing (with round or truncate)
and storing (neither rounding, nor truncating)

Usage example(s):

    ((ScaledDecimal fromString:'0.66666666') withScale:2)
        printDecimalOn:Transcript roundToScale:false truncateToScale:false

    ((ScaledDecimal fromString:'0.66666666') withScale:2)
        printDecimalOn:Transcript roundToScale:true truncateToScale:false

    ((ScaledDecimal fromString:'0.66666666') withScale:2)
        printDecimalOn:Transcript roundToScale:false truncateToScale:true

o  printOn: aStream
append to the argument, aStream, a printed representation of the receiver.
For printout, only scale post-decimal digits are printed
(By default, the printout is rounded to that many digits)

o  printOn: aStream base: base showRadix: showRadix
it doesn't make sense to print a decimal number in a different base

o  printRoundedOn: aStream
append to the argument, aStream, a printed representation of the receiver.
For printout, only scale post-decimal digits are printed,
the printout is rounded to that many digits

Usage example(s):

     ((ScaledDecimal fromString:'0.66666666') withScale:2) printRoundedOn:Transcript   
     ((ScaledDecimal fromString:'0.66666666') withScale:2) printTruncatedOn:Transcript   

o  printTruncatedOn: aStream
append to the argument, aStream, a printed representation of the receiver.
For printout, only scale post-decimal digits are printed,
the printout is truncated to that many digits

Usage example(s):

     String streamContents:[:s |
        ((ScaledDecimal fromString:'0.66666666') withScale:2) printRoundedOn:s
     ] => '0.67'

     String streamContents:[:s |
        ((ScaledDecimal fromString:'0.66666666') withScale:2) printTruncatedOn:s  
     ] => '0.66'

o  storeOn: aStream
notice: we MUST preserve the full internal precision when storing/reloading

o  storeString
((ScaledDecimal fromString:'0.66666666') ) storeString
((ScaledDecimal fromString:'0.66666666') withScale:2 ) storeString
((ScaledDecimal fromString:'1.5') ) storeString
((ScaledDecimal fromString:'1.5') withScale:2 ) storeString
((ScaledDecimal fromString:'1.5') withScale:1 ) storeString
((ScaledDecimal fromString:'1.5') withScale:0 ) storeString

private
o  numerator: numeratorArg denominator: denominatorArg scale: scaleArg
initialize the instance variables.
Will reduce if possible.

o  reduced
reduce the receiver; divide the numerator and denominator by their
greatest common divisor; if the result is integral, return an Integer.
Otherwise, return the normalized receiver.
CAVEAT: bad name; should be called reduce, as it has a side effect
(i.e. this is destructive wrt. the instance values).

o  scale: newScale
set the scale.

o  setNumerator: numeratorArg denominator: denominatorArg scale: scaleArg
initialize the instance variables.
Will reduce if possible.

o  setNumerator: nInteger scale: s
initialize the instance variables, given an integer

o  setScale: newScale
initialize the scale instance variables.

testing
o  isFixedPoint
return true, if the receiver is some kind of fixedPoint number;
true is returned here - the method is redefined from Object.
Obsolete: use isScaledDecimal

o  isScaledDecimal
return true, if the receiver is some kind of fixedPoint number;
true is returned here - the method is redefined from Object.

truncation & rounding
o  fractionPart
extract the after-decimal fraction part,
such that:
(self truncated + self fractionPart) = self

o  roundedToScale
return the receiver rounded to my scale
(i.e. return a number which has the value which is shown when printing)

Usage example(s):

     ((2/3) asScaledDecimal:2)                     
     ((2/3) asScaledDecimal:2) rounded          
     ((2/3) asScaledDecimal:2) roundedToScale     

o  truncatedToScale
return the receiver truncated towards zero to my scale

Usage example(s):

     ((2/3) asScaledDecimal:2)                     
     ((2/3) asScaledDecimal:2) truncated          
     ((2/3) asScaledDecimal:2) truncatedToScale     


Examples:


     |a b r|

     a := (FixedPoint fromString:'123.456').
     b := '1.10' asFixedPoint.
     r := a + b.
     Transcript showCR:r.
     Transcript showCR:(r withScale:2).
     Transcript showCR:(r withScale:1).
     Transcript showCR:(r rounded).
     |a b r|

     a := (FixedPoint fromString:'0.9999999').
     b := 0.0000001 asFixedPoint. 
     r := a + b.
     Transcript showCR:r.
     Transcript showCR:(r withScale:2).
     Transcript showCR:(r withScale:1).
     Transcript showCR:(r rounded).
     |a b r|

     a := (FixedPoint fromString:'0.9999998').
     b := (FixedPoint fromString:'0.0000001').
     r := a + b.
     Transcript showCR:r.
     Transcript showCR:(r withScale:2).
     Transcript showCR:(r withScale:1).
     Transcript showCR:(r rounded).
     |a b r|

     a := (FixedPoint fromString:'1.0').
     b := (FixedPoint fromString:'0.0000001').
     r := a + b.
     Transcript showCR:r.
     Transcript showCR:(r withScale:2).
     Transcript showCR:(r withScale:1).
     Transcript showCR:(r rounded).
     |a b r|

     a := (FixedPoint fromString:'0.99').
     b := (FixedPoint fromString:'0.0000001').
     r := a + b.
     Transcript showCR:r.
     Transcript showCR:(r withScale:2).
     Transcript showCR:(r withScale:1).
     Transcript showCR:(r rounded).


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sat, 27 Jul 2024 04:27:00 GMT