*** empty log message ***
authorps
Fri, 07 Apr 2000 13:46:44 +0200
changeset 5364 a27f5167822c
parent 5363 0070ef95a033
child 5365 95c615a40176
*** empty log message ***
Fraction.st
--- a/Fraction.st	Fri Apr 07 10:16:14 2000 +0200
+++ b/Fraction.st	Fri Apr 07 13:46:44 2000 +0200
@@ -1,6 +1,6 @@
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
-	      All Rights Reserved
+              All Rights Reserved
 
  This software is furnished under a license and may be used
  only in accordance with the terms of that license and with the
@@ -11,10 +11,10 @@
 "
 
 Number subclass:#Fraction
-	instanceVariableNames:'numerator denominator'
-	classVariableNames:'FractionOne FractionZero'
-	poolDictionaries:''
-	category:'Magnitude-Numbers'
+        instanceVariableNames:'numerator denominator'
+        classVariableNames:'FractionOne FractionZero'
+        poolDictionaries:''
+        category:'Magnitude-Numbers'
 !
 
 !Fraction class methodsFor:'documentation'!
@@ -22,7 +22,7 @@
 copyright
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
-	      All Rights Reserved
+              All Rights Reserved
 
  This software is furnished under a license and may be used
  only in accordance with the terms of that license and with the
@@ -41,17 +41,17 @@
     (for exact division).
 
     Mixed mode arithmetic:
-	fraction op fraction    -> fraction
-	fraction op fix         -> fix; scale is fix's scale
-	fraction op integer     -> fraction
-	fraction op float       -> float
+        fraction op fraction    -> fraction
+        fraction op fix         -> fix; scale is fix's scale
+        fraction op integer     -> fraction
+        fraction op float       -> float
 
     [author:]
-	Claus Gittinger
+        Claus Gittinger
 
     [see also:]
-	Number
-	Float Integer FixedPoint 
+        Number
+        Float Integer FixedPoint 
 "
 ! !
 
@@ -59,8 +59,8 @@
 
 initialize
     FractionZero isNil ifTrue:[
-	FractionZero := self numerator:0 denominator:1.
-	FractionOne := self numerator:1 denominator:1
+        FractionZero := self numerator:0 denominator:1.
+        FractionOne := self numerator:1 denominator:1
     ]
 ! !
 
@@ -81,29 +81,29 @@
 
     /* this check allows subclassing .. */
     if (self == Fraction) {
-	if (__bothSmallInteger(num, den)) {
-	    if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) {    /* OBJECT ALLOCATION */
-		OBJ newFraction;
-		int spc;
+        if (__bothSmallInteger(num, den)) {
+            if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) {    /* OBJECT ALLOCATION */
+                OBJ newFraction;
+                int spc;
 
-		__qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
-		__InstPtr(newFraction)->o_class = self;
-		if (__intVal(den) < 0) {
-		    __FractionInstPtr(newFraction)->f_numerator = __MKSMALLINT(- __intVal(num));
-		    __FractionInstPtr(newFraction)->f_denominator = __MKSMALLINT(- __intVal(den));
-		} else {
-		    __FractionInstPtr(newFraction)->f_numerator = num;
-		    __FractionInstPtr(newFraction)->f_denominator = den;
-		}
-		if (num == __MKSMALLINT(1)) {
-		    RETURN ( newFraction );
-		}
-	    }
-	}
+                __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
+                __InstPtr(newFraction)->o_class = self;
+                if (__intVal(den) < 0) {
+                    __FractionInstPtr(newFraction)->f_numerator = __MKSMALLINT(- __intVal(num));
+                    __FractionInstPtr(newFraction)->f_denominator = __MKSMALLINT(- __intVal(den));
+                } else {
+                    __FractionInstPtr(newFraction)->f_numerator = num;
+                    __FractionInstPtr(newFraction)->f_denominator = den;
+                }
+                if (num == __MKSMALLINT(1)) {
+                    RETURN ( newFraction );
+                }
+            }
+        }
     }
 %}.
     newFraction isNil ifTrue:[
-	newFraction :=  self basicNew setNumerator:num denominator:den.
+        newFraction :=  self basicNew setNumerator:num denominator:den.
     ].
     ^ newFraction reduced
 ! !
@@ -114,8 +114,8 @@
     "return the constant pi as Fraction"
 
     ^ self 
-	numerator:  31415926535897932384626434
-	denominator:10000000000000000000000000
+        numerator:  31415926535897932384626434
+        denominator:10000000000000000000000000
 
     "
      Fraction pi         
@@ -175,18 +175,18 @@
     |n d|
 
     (aNumber isMemberOf:SmallInteger) ifTrue:[
-	^ (self class numerator:(numerator * aNumber)
-		    denominator:denominator)
+        ^ (self class numerator:(numerator * aNumber)
+                    denominator:denominator)
     ].
     aNumber isFraction ifTrue:[
-	aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
-	    n := numerator * aNumber numerator.
-	    d := denominator * aNumber denominator.
-	    ^ (self class numerator:n denominator:d)
-	]
+        aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
+            n := numerator * aNumber numerator.
+            d := denominator * aNumber denominator.
+            ^ (self class numerator:n denominator:d)
+        ]
     ].
     (aNumber isMemberOf:Float) ifTrue:[
-	^ (numerator * aNumber) / denominator
+        ^ (numerator * aNumber) / denominator
     ].
     ^ aNumber productFromFraction:self
 
@@ -199,26 +199,26 @@
     |n d|
 
     (aNumber isMemberOf:SmallInteger) ifTrue:[
-	^ (self class numerator:(numerator + (denominator * aNumber))
-		    denominator:denominator)
+        ^ (self class numerator:(numerator + (denominator * aNumber))
+                    denominator:denominator)
     ].
     aNumber isFraction ifTrue:[
-	aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
-	    n := aNumber numerator.
-	    d := aNumber denominator.
+        aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
+            n := aNumber numerator.
+            d := aNumber denominator.
 
-	    "save a multiplication if possible"
-	    denominator == d ifTrue:[
-		n := numerator + n
-	    ] ifFalse:[
-		n := (numerator * d) + (n * denominator).
-		d := denominator * d.
-	    ].
-	    ^ (self class numerator:n denominator:d)
-	]
+            "save a multiplication if possible"
+            denominator == d ifTrue:[
+                n := numerator + n
+            ] ifFalse:[
+                n := (numerator * d) + (n * denominator).
+                d := denominator * d.
+            ].
+            ^ (self class numerator:n denominator:d)
+        ]
     ].
     (aNumber isMemberOf:Float) ifTrue:[
-	^ aNumber + (numerator asFloat / denominator asFloat)
+        ^ aNumber + (numerator asFloat / denominator asFloat)
     ].
     ^ aNumber sumFromFraction:self
 
@@ -231,26 +231,26 @@
     |n d|
 
     (aNumber isMemberOf:SmallInteger) ifTrue:[
-	^ (self class numerator:(numerator - (denominator * aNumber))
-		    denominator:denominator)
+        ^ (self class numerator:(numerator - (denominator * aNumber))
+                    denominator:denominator)
     ].
     aNumber isFraction ifTrue:[
-	aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
-	    n := aNumber numerator.
-	    d := aNumber denominator.
+        aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
+            n := aNumber numerator.
+            d := aNumber denominator.
 
-	    "save a multiplication if possible"
-	    denominator == d ifTrue:[
-		n := numerator - n
-	    ] ifFalse:[
-		n := (numerator * d) - (n * denominator).
-		d := denominator * d
-	    ].
-	    ^ (self class numerator:n denominator:d)
-	]
+            "save a multiplication if possible"
+            denominator == d ifTrue:[
+                n := numerator - n
+            ] ifFalse:[
+                n := (numerator * d) - (n * denominator).
+                d := denominator * d
+            ].
+            ^ (self class numerator:n denominator:d)
+        ]
     ].
     (aNumber isMemberOf:Float) ifTrue:[
-	^ (numerator asFloat / denominator asFloat) - aNumber
+        ^ (numerator asFloat / denominator asFloat) - aNumber
     ].
     ^ aNumber differenceFromFraction:self
 
@@ -271,18 +271,18 @@
     |n d|
 
     (aNumber isMemberOf:SmallInteger) ifTrue:[
-	^ (self class numerator:numerator
-		    denominator:(denominator * aNumber))
+        ^ (self class numerator:numerator
+                    denominator:(denominator * aNumber))
     ].
     aNumber isFraction ifTrue:[
-	aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
-	    n := numerator * aNumber denominator.
-	    d := denominator * aNumber numerator.
-	    ^ (self class numerator:n denominator:d)
-	]
+        aNumber isFixedPoint ifFalse:[  "/ the value was corrent, but the scale is lost
+            n := numerator * aNumber denominator.
+            d := denominator * aNumber numerator.
+            ^ (self class numerator:n denominator:d)
+        ]
     ].
     (aNumber isMemberOf:Float) ifTrue:[
-	^ numerator / (denominator * aNumber)
+        ^ numerator / (denominator * aNumber)
     ].
     ^ aNumber quotientFromFraction:self
 
@@ -310,8 +310,8 @@
     "optional - could use inherited method ..."
 
     ^ self class 
-	numerator:(numerator negated)
-	denominator:denominator
+        numerator:(numerator negated)
+        denominator:denominator
 
     "Modified: 5.11.1996 / 10:29:11 / cg"
 !
@@ -321,8 +321,8 @@
 
     numerator == 1 ifTrue:[^ denominator].
     ^ self class 
-	numerator:denominator
-	denominator:numerator
+        numerator:denominator
+        denominator:numerator
 
     "Modified: 5.11.1996 / 10:29:22 / cg"
 ! !
@@ -413,17 +413,17 @@
     |d n|
 
     (aNumber isMemberOf:SmallInteger) ifTrue:[
-	^ numerator < (denominator * aNumber)
+        ^ numerator < (denominator * aNumber)
     ].
     aNumber isFraction ifTrue:[
-	d := aNumber denominator.
-	n := aNumber numerator.
+        d := aNumber denominator.
+        n := aNumber numerator.
 
-	"/ save a multiplication if possible
-	d == denominator ifTrue:[
-	    ^ numerator < n
-	].
-	^ (numerator * d) < (denominator * n)
+        "/ save a multiplication if possible
+        d == denominator ifTrue:[
+            ^ numerator < n
+        ].
+        ^ (numerator * d) < (denominator * n)
     ].
     ^ aNumber lessFromFraction:self
 
@@ -435,16 +435,18 @@
      as the receiver, false otherwise"
 
     (aNumber isMemberOf:SmallInteger) ifTrue:[
-	(denominator = 1) ifFalse:[^ false].
-	^ numerator = aNumber
+        (denominator = 1) ifFalse:[^ false].
+        ^ numerator = aNumber
     ].
     aNumber isFraction ifTrue:[
-	(numerator = aNumber numerator) ifFalse:[^ false].
-	^ denominator = aNumber denominator
+        denominator = aNumber denominator ifTrue:[
+            ^ numerator = aNumber numerator
+        ].
+        ^ self sameFractionValueAs:aNumber
     ].
     (aNumber isInteger) ifTrue:[
-	(denominator = 1) ifFalse:[^ false].
-	^ numerator = aNumber
+        (denominator = 1) ifFalse:[^ false].
+        ^ numerator = aNumber
     ].
     ^ self retry:#= coercing:aNumber
 
@@ -459,17 +461,17 @@
     |d n|
 
     (aNumber isMemberOf:SmallInteger) ifTrue:[
-	^ numerator > (denominator * aNumber)
+        ^ numerator > (denominator * aNumber)
     ].
     aNumber isFraction ifTrue:[
-	d := aNumber denominator.
-	n := aNumber numerator.
+        d := aNumber denominator.
+        n := aNumber numerator.
 
-	"/ save a multiplication if possible
-	d == denominator ifTrue:[
-	    ^ numerator > n
-	].
-	^ (numerator * d) > (denominator * n)
+        "/ save a multiplication if possible
+        d == denominator ifTrue:[
+            ^ numerator > n
+        ].
+        ^ (numerator * d) > (denominator * n)
     ].
     ^ self retry:#> coercing:aNumber
 
@@ -496,6 +498,20 @@
      0.25 hash         
      0.4 hash         
     "
+!
+
+sameFractionValueAs:aNumber
+    "return true, if the argument represents the same numeric value
+     as the receiver, false otherwise"
+
+    |rSelf rNum|
+
+    rSelf := self reduced.
+    rNum := aNumber reduced.
+    rSelf denominator = rNum denominator ifTrue:[
+        ^ rSelf numerator = rNum numerator
+    ].
+    ^ false
 ! !
 
 !Fraction methodsFor:'double dispatching'!
@@ -510,8 +526,8 @@
     "sent when an integer does not know how to subtract the receiver, a fraction"
 
     ^ (self class 
-	numerator:((anInteger * denominator) - numerator)
-	denominator:denominator)
+        numerator:((anInteger * denominator) - numerator)
+        denominator:denominator)
 
     "Modified: 28.7.1997 / 19:08:53 / cg"
 !
@@ -532,8 +548,8 @@
     "sent when an integer does not know how to multiply the receiver, a fraction"
 
     ^ (self class 
-	numerator:(anInteger * numerator)
-	denominator:denominator)
+        numerator:(anInteger * numerator)
+        denominator:denominator)
 
     "Modified: 28.7.1997 / 19:06:22 / cg"
 !
@@ -548,8 +564,8 @@
     "sent when an integer does not know how to divide by the receiver, a fraction"
 
     ^ (self class 
-	numerator:(anInteger * denominator)
-	denominator:numerator)
+        numerator:(anInteger * denominator)
+        denominator:numerator)
 
     "Modified: 28.7.1997 / 19:08:46 / cg"
 !
@@ -564,8 +580,8 @@
     "sent when an integer does not know how to add the receiver, a fraction"
 
     ^ (self class 
-	numerator:(numerator + (anInteger * denominator))
-	denominator:denominator)
+        numerator:(numerator + (anInteger * denominator))
+        denominator:denominator)
 
     "Modified: 28.7.1997 / 19:08:40 / cg"
 ! !
@@ -592,8 +608,8 @@
 
     den := denominator.
     den < 0 ifTrue:[
-	numerator := numerator negated.
-	den := denominator := den negated.
+        numerator := numerator negated.
+        den := denominator := den negated.
     ].
 
     den == 1 ifTrue:[^ numerator].
@@ -602,13 +618,13 @@
 
     gcd := numerator gcd:den.
     (gcd ~~ 1) ifTrue:[
-	numerator := numerator // gcd.
-	denominator := den := den // gcd.
-	den < 0 ifTrue:[
-	    numerator := numerator negated.
-	    den := denominator := den negated.
-	].
-	(den == 1) ifTrue:[^ numerator].
+        numerator := numerator // gcd.
+        denominator := den := den // gcd.
+        den < 0 ifTrue:[
+            numerator := numerator negated.
+            den := denominator := den negated.
+        ].
+        (den == 1) ifTrue:[^ numerator].
     ].
     ^ self
 !
@@ -643,7 +659,7 @@
     "return true if the receiver is negative"
 
     (numerator < 0) ifTrue:[
-	^ (denominator < 0) not
+        ^ (denominator < 0) not
     ].
     ^ (denominator < 0)
 ! !
@@ -654,7 +670,7 @@
     "extract the after-decimal fraction part."
 
     numerator < denominator ifTrue:[
-	^ self
+        ^ self
     ].
     ^ super fractionPart
 
@@ -672,7 +688,7 @@
     "extract the pre-decimal integer part."
 
     numerator < denominator ifTrue:[
-	^ 0
+        ^ 0
     ].
     ^ super integerPart
 
@@ -694,9 +710,9 @@
     |t|
 
     self negative ifTrue:[
-	t := self - (1/2)
+        t := self - (1/2)
     ] ifFalse:[
-	t := self + (1/2)
+        t := self + (1/2)
     ].
     ^ t truncated.
 
@@ -730,6 +746,6 @@
 !Fraction class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Fraction.st,v 1.48 2000-03-24 11:54:39 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Fraction.st,v 1.49 2000-04-07 11:46:44 ps Exp $'
 ! !
 Fraction initialize!