|
Class: Fraction
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
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
Number
FixedPoint
Float
ShortFloat
LongFloat
Integer
Complex
class initialization
-
initialize
-
coercing & converting
-
coerce: aNumber
-
convert the argument aNumber into an instance of the receiver's class and return it.
constants
-
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
|
-
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
|
-
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
|
-
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
|
-
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
|
-
unity
-
return the neutral element for multiplication (1 / 1)
-
zero
-
return the neutral element for addition (0 / 1)
instance creation
-
new
-
create and return a new fraction with value 0
-
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
|
-
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
|
-
readFrom: aStringOrStream onError: exceptionBlock
-
sigh - care for subclasses...
queries
-
isBuiltInClass
-
return true if this class is known by the run-time-system.
Here, true is returned for myself, false for subclasses.
accessing
-
denominator
-
return the denominator
-
numerator
-
return the numerator
arithmetic
-
* aNumber
-
return the product of the receiver and the argument.
usage example(s):
-
+ aNumber
-
return the sum of the receiver and the argument, aNumber
usage example(s):
-
- 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)
|
-
/ aNumber
-
return the quotient of the receiver and the argument, aNumber
-
// 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].
|
-
negated
-
optional - could use inherited method ...
-
reciprocal
-
optional - could use inherited method ...
coercing & converting
-
asFixedPoint
-
return the receiver as fixedPoint number.
Q: what should the scale be here ?
usage example(s):
-
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
|
-
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
|
-
asFraction
-
return the receiver as fraction - that's the receiver itself
-
asInteger
-
return an integer with my value - will usually truncate
-
asLargeFloat
-
return a large float with (approximately) my value
usage example(s):
(5/9) asLargeFloat
(500000000000/900000000000) asLargeFloat
(500000000000/9) asLargeFloat
|
-
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
|
-
asLargeInteger
-
return an integer with my value - will usually truncate
-
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
|
-
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
|
-
asShortFloat
-
return a short float with (approximately) my value
usage example(s):
(5/9) asShortFloat
(500000000000/900000000000) asShortFloat
(500000000000/9) asShortFloat
|
-
coerce: aNumber
-
convert the argument aNumber into an instance of the receiver's class and return it.
-
generality
-
return the generality value - see ArithmeticValue>>retry:coercing:
comparing
-
< aNumber
-
return true if the receiver is less
than aNumber, false otherwise.
-
= aNumber
-
return true, if the argument represents the same numeric value
as the receiver, false otherwise
-
> aNumber
-
return true if the receiver is greater
than aNumber, false otherwise.
-
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
|
-
sameFractionValueAs: aNumber
-
return true, if the argument represents the same numeric value
as the receiver, false otherwise
double dispatching
-
differenceFromFixedPoint: aFixedPoint
-
save a multiplication if possible
-
differenceFromFloat: aFloat
-
sent when a float does not know how to subtract the receiver, a fraction
-
differenceFromFraction: aFraction
-
save a multiplication if possible
-
differenceFromInteger: anInteger
-
sent when an integer does not know how to subtract the receiver, a fraction
-
equalFromFraction: aFraction
-
must always be reduced
-
equalFromInteger: anInteger
-
sent when an integer does not know how to compare to the receiver, a fraction
-
lessEqFromInteger: anInteger
-
sent when an integer does not know how to compare to the receiver, a fraction
-
lessFromFraction: aFraction
-
sent when a fraction does not know how to compare to the receiver.
Return true if aFraction < self.
-
lessFromInteger: anInteger
-
sent when an integer does not know how to compare to the receiver, a fraction.
Return true if anInteger < self.
-
productFromFixedPoint: aFixedPoint
-
((1/3) asFixedPoint:2) * 2
((1/3) asFixedPoint:2) * (1/2)
((1/3) asFixedPoint:2) * (3/2)
-
productFromFloat: aFloat
-
sent when a float does not know how to multiply the receiver, a fraction
-
productFromFraction: aFraction
-
((1/3) asFixedPoint:2) * 2
((1/3) asFixedPoint:2) * (1/2)
((1/3) asFixedPoint:2) * (3/2)
-
productFromInteger: anInteger
-
sent when an integer does not know how to multiply the receiver, a fraction
-
quotientFromFixedPoint: aFixedPoint
-
Return the quotient of the argument, aFixedPoint and the receiver.
Sent when aFixedPoint does not know how to divide by the receiver.
-
quotientFromFloat: aFloat
-
Return the quotient of the argument, aFloat and the receiver.
Sent when aFloat does not know how to divide by the receiver.
-
quotientFromFraction: aFraction
-
Return the quotient of the argument, aFraction and the receiver.
Sent when aFraction does not know how to divide by the receiver.
-
quotientFromInteger: anInteger
-
Return the quotient of the argument, anInteger and the receiver.
Sent when anInteger does not know how to divide by the receiver.
-
raisedFromFloat: aFloat
-
aFloat does not know how to be raised to the receiver
-
sumFromFixedPoint: aFixedPoint
-
save a multiplication if possible
-
sumFromFloat: aFloat
-
sent when a float does not know how to add the receiver, a fraction
-
sumFromFraction: aFraction
-
save a multiplication if possible
-
sumFromInteger: anInteger
-
sent when an integer does not know how to add the receiver, a fraction
inspecting
-
inspectorExtraAttributes ( an extension from the stx:libtool package )
-
extra (pseudo instvar) entries to be shown in an inspector.
-
inspectorValueListIconFor: anInspector ( an extension from the stx:libtool package )
-
returns the icon to be shown alongside the value list of an inspector
printing & storing
-
printOn: aStream
-
append a printed representation of the receiver to the
argument, aStream
private
-
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).
-
setNumerator: num denominator: den
-
set both numerator and denominator
testing
-
isFraction
-
return true, if the receiver is some kind of fraction;
true is returned here - the method is redefined from Object.
-
isLiteral
-
return true, if the receiver can be used as a literal constant in ST syntax
(i.e. can be used in constant arrays)
-
negative
-
return true if the receiver is less than zero
truncation & rounding
-
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
|
-
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
|
-
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
|
-
truncated
-
return the receiver truncated towards zero as Integer
usage example(s):
(3/2) truncated
(3/2) negated truncated
|
visiting
-
acceptVisitor: aVisitor with: aParameter
-
dispatch for visitor pattern; send #visitFraction:with: to aVisitor
|