eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'Fraction':

Home

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

Class: Fraction


Inheritance:

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

Package:
stx:libbasic
Category:
Magnitude-Numbers
Version:
rev: 1.110 date: 2019/06/07 00:34:43
user: cg
file: Fraction.st directory: libbasic
module: stx stc-classLibrary: libbasic
Author:
Claus Gittinger

Description:


Instances of Fraction represent fractional numbers consisting of
a numerator and denominator. Both are themselfes arbitrary precision
integers.
Fractions are usually created by dividing Integers using / (for exact division).
Notice, that all operations on fractions reduce their result; this means, that
the result of a fraction-operation may return an integer.
Aka:
    (1 / 7) * 7   ->  1  (not 0.99999999...)

Mixed mode arithmetic:
    fraction op fraction    -> fraction/integer
    fraction op fix         -> fix; scale is fix's scale
    fraction op integer     -> fraction/integer
    fraction op float       -> float


[classVariables:]
    PrintWholeNumbers       Boolean        experimental:
                                            controls how fractions which are greater than 1 are printed.
                                            if true, print them as a sum of an integral and the fractional part.
                                            (Large ones are easier to read this way)
                                                 (17/3) printString  -> '(5+(2/3))'
                                            for now, the default is false, for backward compatibility


Related information:

    Number
    FixedPoint
    Float
    ShortFloat
    LongFloat
    Integer
    Complex

Class protocol:

class initialization
o  initialize

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

constants
o  e
return an approximation of the constant e as Fraction.
The approx. returned here has an error smaller than representable by float instances
(roughly 26 valid digits)

usage example(s):

E := nil
    
     Fraction e
     Fraction e asFloat - Float e
     Fraction e asLongFloat - LongFloat e
     Float e
     FixedPoint e

usage example(s):

Modified (comment): / 06-06-2019 / 17:10:56 / Claus Gittinger

o  e_approximation
return an approximation of e as Fraction.
The approx. returned is good for 6 valid digits and has an error of less than -2.67-07.
The value might be useful to avoid floating point numbers in graphic rendering code,
where 6 digits of precision are usually good enough.

usage example(s):

     Fraction e
     Fraction e asFloat               
     Fraction e_approximation asFloat 
     
     (Fraction e - Fraction e_approximation asFloat) abs
     (Float e - Fraction e_approximation asFloat) abs

     19/7 can be used as an approx with ~1% error:
         Float e - (19/7) asFloat
         
     87/32 is another candidate:
         Float e - (87/32) asFloat 

     and 106/39:
         Float e - (106/39) asFloat 

o  pi
return an approximation of the constant pi as Fraction.
The approx. returned here has an error smaller than representable by float instances
(roughly 26 valid digits)

usage example(s):

     Fraction pi
     Fraction pi asFloat - Float pi
     Fraction pi asLongFloat - LongFloat pi
     Float pi

o  pi1000
return an approximation of the constant pi as Fraction (>= 1000 valid decimal digits).

usage example(s):

     Pi_1000 := nil.
     Fraction pi1000
     Fraction pi1000 asLongFloat - LongFloat pi
     LongFloat pi

o  pi_approximation
return an approximation of the constant pi as Fraction.
The approx. returned is good for 6 valid digits and has an error of less than -2.67-07.
The value might be useful to avoid floating point numbers in graphic rendering code,
where 6 digits of precision are usually good enough.

usage example(s):

     Fraction pi
     Fraction pi asFloat
     
     (Fraction pi - Fraction pi_approximation asFloat) abs
     (Float pi - Fraction pi_approximation asFloat) abs

     22/7 can be used as an approx with 1% error:
         Float pi - (22/7) asFloat

o  unity
return the neutral element for multiplication (1 / 1)

o  zero
return the neutral element for addition (0 / 1)

instance creation
o  new
create and return a new fraction with value 0

o  numerator: num denominator: den
create and return a new fraction with numerator num and denominator den.
Notice: stc inlines this message if sent to the global named Fraction.

usage example(s):

     Fraction numerator:1 denominator:3    -> (1/3)
     Fraction numerator:-1 denominator:3   -> (-1/3)
     Fraction numerator:1 denominator:-3   -> (-1/3)
     Fraction numerator:-1 denominator:-3  -> (1/3)

     Fraction numerator:2 denominator:3
     Fraction numerator:2 denominator:6

     Fraction numerator:1 denominator:0  -> error
     Fraction numerator:2 denominator:0  -> error

     Fraction numerator:5 denominator:10
     Fraction numerator:50 denominator:100
     Fraction numerator:8 denominator:16

o  readDecimalFractionFrom: aStringOrStream onError: exceptionBlock
Read an arbitrary number (>0) of digits representing a decimal fraction.

usage example(s):

     Fraction readDecimalFractionFrom:'1'   onError:[nil]     -> 0.1
     Fraction readDecimalFractionFrom:'123' onError:[nil]     -> 0.123
     Fraction readDecimalFractionFrom:'5'   onError:[nil]     -> 0.5
     Fraction readDecimalFractionFrom:'005' onError:[nil]     -> 0.005
     Fraction readDecimalFractionFrom:''    onError:[nil]     -> nil
     Fraction readDecimalFractionFrom:'aa'  onError:[nil]     -> nil

o  readFrom: aStringOrStream onError: exceptionBlock
sigh - care for subclasses...

queries
o  isBuiltInClass
return true if this class is known by the run-time-system.
Here, true is returned for myself, false for subclasses.


Instance protocol:

accessing
o  denominator
return the denominator

o  numerator
return the numerator

arithmetic
o  * aNumber
return the product of the receiver and the argument.

usage example(s):

        2/3 * 3 asLongFloat

o  + aNumber
return the sum of the receiver and the argument, aNumber

usage example(s):

        2/3 + 10 asLongFloat

o  - aNumber
return the difference of the receiver and the argument, aNumber

usage example(s):

     (1/3) - (1/9)
     (1/9) - (1/3)
     (999/1000) - (1/1000)
     (999/1000) - (1/1000000)
     (999000/1000000) - (1/1000000)

o  / aNumber
return the quotient of the receiver and the argument, aNumber

o  // aNumber
return the integer quotient of dividing the receiver by aNumber with
truncation towards negative infinity.

usage example(s):

     0.5 // 1
     -0.5 // 1
     (1/2) // 1  = 0 ifFalse:[self halt].
     (-1/2) // 1 = -1 ifFalse:[self halt].

o  negated
optional - could use inherited method ...

o  reciprocal
optional - could use inherited method ...

coercing & converting
o  asFixedPoint
return the receiver as fixedPoint number.
Q: what should the scale be here ?

usage example(s):

     (1/2) asFixedPoint

o  asFixedPoint: scale
return the receiver as fixedPoint number, with the given number
of post-decimal-point digits.

usage example(s):

     (1/2) asFixedPoint:2
     (1/3) asFixedPoint:2
     (1/3) asFixedPoint:5
     (2/3) asFixedPoint:2
     (2/3) asFixedPoint:5

o  asFloat
return a float with (approximately) my value.
Since floats have a limited precision, you usually loose bits when doing this.

usage example(s):

      (5/9) asFloat
      (-5/9) asFloat
      (500000000000/900000000000) asFloat
      (-500000000000/900000000000) asFloat
      (500000000000/9) asFloat
      (5/900000000000) asFloat
      89012345678901234567 asFloat / 123456789123456789 asFloat
      (89012345678901234567 / 123456789123456789) asFloat

      (
       180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
	/
       180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
      ) asFloat

      180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
	 asFloat /
      180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
	 asFloat

o  asFraction
return the receiver as fraction - that's the receiver itself

o  asInteger
return an integer with my value - will usually truncate

o  asLargeFloat
return a large float with (approximately) my value

usage example(s):

      (5/9) asLargeFloat
      (500000000000/900000000000) asLargeFloat
      (500000000000/9) asLargeFloat

o  asLargeFloatPrecision: n
Answer a Floating point with arbitrary precision
close to the receiver.

usage example(s):

      (5/9) asFloat 0.555555555555556
      (5/9) asLargeFloatPrecision:200 0.555556
      (5/9) asLargeFloat
      
      (500000000000/900000000000) asFloat * 900000000000 - 500000000000
      ((500000000000/900000000000) asLargeFloatPrecision:200) * 900000000000 - 500000000000
      (500000000000/900000000000) asLargeFloat * 900000000000 - 500000000000
      
      (500000000000/9) asLargeFloatPrecision:200
      (500000000000/9) asLargeFloat:200

o  asLargeInteger
return an integer with my value - will usually truncate

o  asLongFloat
return a long float with (approximately) my value.
Since floats have a limited precision, you usually loose bits when doing this.

usage example(s):

      (5/9) asLongFloat
      (-5/9) asLongFloat
      (Fraction basicNew setNumerator:500000000000 denominator:900000000000) asLongFloat = (5/9) asLongFloat
      (Fraction basicNew setNumerator:500000000001 denominator:900000000000) asLongFloat = (5/9) asLongFloat
      (500000000001/900000000000) asLongFloat
      (-500000000001/900000000000) asLongFloat
      (500000000001/900000000000) asLongFloat = (5/9) asLongFloat

      (500000000000/9) asLongFloat
      (5/900000000000) asLongFloat
      89012345678901234567 asFloat / 123456789123456789 asLongFloat
      (89012345678901234567 / 123456789123456789) asLongFloat
      (-89012345678901234567 / 123456789123456789) asLongFloat

      (
       180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
	/
       180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
      ) asLongFloat

      180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
	 asLongFloat /
      180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
	 asLongFloat

o  asQuadFloat
return a QuadFloat with (approximately) my value.
Since floats have a limited precision, you usually loose bits when doing this.

usage example(s):

      (5/9) asQuadFloat
      (-5/9) asQuadFloat
      (Fraction basicNew setNumerator:500000000000 denominator:900000000000) asQuadFloat = (5/9) asQuadFloat
      (Fraction basicNew setNumerator:500000000001 denominator:900000000000) asQuadFloat = (5/9) asQuadFloat
      (500000000001/900000000000) asQuadFloat
      (-500000000001/900000000000) asQuadFloat
      (500000000001/900000000000) asQuadFloat = (5/9) asQuadFloat

      (500000000000/9) asQuadFloat
      (5/900000000000) asQuadFloat
      89012345678901234567 asFloat / 123456789123456789 asQuadFloat
      (89012345678901234567 / 123456789123456789) asQuadFloat
      (-89012345678901234567 / 123456789123456789) asQuadFloat

      (
       180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
        /
       180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
      ) asQuadFloat

      180338700661043257034670206806167960222709397862806840937993331366591676308781197477183367018067356365812757479444845320188679437752013593674158587947149815441890236037219685250845721864713487208757788709113534916165172927384095182655935222723385253851776639985379367854545495930551624041981995105743408203125
         asQuadFloat /
      180331613628627651967947866455016278082980736719853750685591387625058011528928110602436691256100991596843001549483950600930062886280582766771424470965440873615557144641435276844465734361353086032476712374317224249252177316815544331763696909434844464464323192083930469387098582956241443753242492675781250
         asQuadFloat

o  asShortFloat
return a short float with (approximately) my value

usage example(s):

      (5/9) asShortFloat
      (500000000000/900000000000) asShortFloat
      (500000000000/9) asShortFloat

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:

comparing
o  < aNumber
return true if the receiver is less
than aNumber, false otherwise.

o  = aNumber
return true, if the argument represents the same numeric value
as the receiver, false otherwise

o  > aNumber
return true if the receiver is greater
than aNumber, false otherwise.

o  hash
return a number for hashing; redefined, since fractions compare
by numeric value (i.e. (1/2) = 0.5), hash values must be the same

usage example(s):

     3 hash
     (9/3) hash
     3.0 hash
     (1/2) hash
     (1/4) hash
     0.0 hash
     0.5 hash
     0.25 hash
     0.4 hash

     0.25 hash
     -0.25 hash
     (1/4) hash
     (-1/4) hash

o  sameFractionValueAs: aNumber
return true, if the argument represents the same numeric value
as the receiver, false otherwise

double dispatching
o  differenceFromFixedPoint: aFixedPoint
save a multiplication if possible

o  differenceFromFloat: aFloat
sent when a float does not know how to subtract the receiver, a fraction

o  differenceFromFraction: aFraction
save a multiplication if possible

o  differenceFromInteger: anInteger
sent when an integer does not know how to subtract the receiver, a fraction

o  equalFromFraction: aFraction
must always be reduced

o  equalFromInteger: anInteger
sent when an integer does not know how to compare to the receiver, a fraction

o  lessEqFromInteger: anInteger
sent when an integer does not know how to compare to the receiver, a fraction

o  lessFromFraction: aFraction
sent when a fraction does not know how to compare to the receiver.
Return true if aFraction < self.

o  lessFromInteger: anInteger
sent when an integer does not know how to compare to the receiver, a fraction.
Return true if anInteger < self.

o  productFromFixedPoint: aFixedPoint
((1/3) asFixedPoint:2) * 2
((1/3) asFixedPoint:2) * (1/2)
((1/3) asFixedPoint:2) * (3/2)

o  productFromFloat: aFloat
sent when a float does not know how to multiply the receiver, a fraction

o  productFromFraction: aFraction
((1/3) asFixedPoint:2) * 2
((1/3) asFixedPoint:2) * (1/2)
((1/3) asFixedPoint:2) * (3/2)

o  productFromInteger: anInteger
sent when an integer does not know how to multiply the receiver, a fraction

o  quotientFromFixedPoint: aFixedPoint
Return the quotient of the argument, aFixedPoint and the receiver.
Sent when aFixedPoint does not know how to divide by the receiver.

o  quotientFromFloat: aFloat
Return the quotient of the argument, aFloat and the receiver.
Sent when aFloat does not know how to divide by the receiver.

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.

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.

o  raisedFromFloat: aFloat
aFloat does not know how to be raised to the receiver

o  sumFromFixedPoint: aFixedPoint
save a multiplication if possible

o  sumFromFloat: aFloat
sent when a float does not know how to add the receiver, a fraction

o  sumFromFraction: aFraction
save a multiplication if possible

o  sumFromInteger: anInteger
sent when an integer does not know how to add the receiver, a fraction

inspecting
o  inspectorExtraAttributes
( an extension from the stx:libtool package )
extra (pseudo instvar) entries to be shown in an inspector.

o  inspectorValueListIconFor: anInspector
( an extension from the stx:libtool package )
returns the icon to be shown alongside the value list of an inspector

printing & storing
o  printOn: aStream
append a printed representation of the receiver to the
argument, aStream

private
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  setNumerator: num denominator: den
set both numerator and denominator

testing
o  isFraction
return true, if the receiver is some kind of fraction;
true is returned here - the method is redefined from Object.

o  isLiteral
return true, if the receiver can be used as a literal constant in ST syntax
(i.e. can be used in constant arrays)

o  negative
return true if the receiver is less than zero

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

usage example(s):

     (3/2) fractionPart + (3/2) truncated
     (-3/2) fractionPart + (-3/2) truncated

     (3/2) fractionPart
     (-3/2) fractionPart
     (3/2) asFloat fractionPart
     (-3/2) asFloat fractionPart
     (2/3) fractionPart
     ((3/2)*(15/4)) fractionPart
     ((2/3)*(4/15)) fractionPart

o  integerPart
extract the pre-decimal integer part.

usage example(s):

     (3/2) integerPart
     (-3/2) integerPart
     (2/3) integerPart
     ((3/2)*(15/4)) integerPart
     ((2/3)*(4/15)) integerPart

o  rounded
return the receiver rounded to the nearest integer as integer

usage example(s):

     (1/3) rounded
     (1/3) negated rounded
     (1/2) rounded
     (1/2) negated rounded
     0.5 rounded
     -0.5 rounded
     (2/3) rounded
     (2/3) negated rounded

o  truncated
return the receiver truncated towards zero as Integer

usage example(s):

     (3/2) truncated
     (3/2) negated truncated

visiting
o  acceptVisitor: aVisitor with: aParameter
dispatch for visitor pattern; send #visitFraction:with: to aVisitor



ST/X 7.2.0.0; WebServer 1.670 at bd0aa1f87cdd.unknown:8081; Thu, 28 Mar 2024 19:14:19 GMT