Fraction.st
changeset 19259 9e95248432bd
parent 19248 a34488b9f1e6
child 19261 02cb0c66a1b8
--- a/Fraction.st	Fri Feb 26 20:48:29 2016 +0100
+++ b/Fraction.st	Fri Feb 26 21:53:13 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
 	      All Rights Reserved
@@ -88,56 +90,77 @@
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
     if (self == Fraction.Class) {
-	return context._RETURN(new STFraction(num, den));
+        return context._RETURN(new STFraction(num, den));
     }
 #else
     /* this check allows subclassing .. */
     if (self == Fraction) {
-	if (__bothSmallInteger(num, den)) {
-	    if (den != __mkSmallInteger(0)) {
-		if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) {    /* OBJECT ALLOCATION */
-		    OBJ newFraction;
-		    int spc;
-		    INT iDen;
+        if (__bothSmallInteger(num, den)) {
+            if (den != __mkSmallInteger(0)) {
+                if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) {    /* OBJECT ALLOCATION */
+                    OBJ newFraction;
+                    int spc;
+                    INT iDen;
+                    INT iNum;
+
+                    __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
+                    __InstPtr(newFraction)->o_class = self;
+                    __qSTORE(newFraction, self);
+
+                    iDen = __intVal(den);
+                    iNum = __intVal(num);
 
-		    __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
-		    __InstPtr(newFraction)->o_class = self;
-		    __qSTORE(newFraction, self);
-		    iDen = __intVal(den);
-		    if (iDen != 0) {
-			if (iDen < 0) {
-			    __FractionInstPtr(newFraction)->f_numerator = __mkSmallInteger(- __intVal(num));
-			    __FractionInstPtr(newFraction)->f_denominator = __mkSmallInteger(- iDen);
-			} else {
-			    __FractionInstPtr(newFraction)->f_numerator = num;
-			    __FractionInstPtr(newFraction)->f_denominator = den;
-			}
-			if (num == __mkSmallInteger(1)) {
-			    /* no need to reduce */
-			    RETURN ( newFraction );
-			}
-		    }
-		}
-	    }
-	}
+                    if (iDen < 0) {
+                        iNum = -iNum;
+                        iDen = -iDen;
+                    }
+                    while ( (((iNum | iDen) & 1) == 0) && ( iNum != 0) && ( iDen != 0)) {
+                        /* both even and non-zero */
+                        iNum = iNum >> 1;
+                        iDen = iDen >> 1;
+                    }
+                    if (iNum >= _MAX_INT) {
+                        __FractionInstPtr(newFraction)->f_numerator = __MKINT(iNum);
+                    } else {
+                        __FractionInstPtr(newFraction)->f_numerator = __MKSMALLINT(iNum);
+                    }
+                    if (iDen >= _MAX_INT) {
+                        __FractionInstPtr(newFraction)->f_denominator = __MKINT(iDen);
+                    } else {
+                        __FractionInstPtr(newFraction)->f_denominator = __MKSMALLINT(iDen);
+                    }
+                    if (iNum == 1) {
+                        /* no need to reduce */
+                        RETURN ( newFraction );
+                    }
+                }
+            }
+        }
     }
 #endif /* not __SCHTEAM__ */
 %}.
     den = 0 ifTrue:[
-	^ ZeroDivide raiseRequestWith:thisContext.
+        ^ ZeroDivide raiseRequestWith:thisContext.
     ].
     newFraction isNil ifTrue:[
-	newFraction := self basicNew setNumerator:num denominator:den.
+        newFraction := self basicNew setNumerator:num denominator:den.
     ].
     ^ newFraction reduced
 
     "
-     Fraction numerator:1 denominator:3
-     Fraction numerator:2 denominator:6
+     Fraction numerator:1 denominator: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:1 denominator:0
-     Fraction numerator:2 denominator:0
+     Fraction numerator:5 denominator:10    
+     Fraction numerator:50 denominator:100  
+     Fraction numerator:8 denominator:16  
     "
+
+    "Modified: / 26-02-2016 / 21:52:05 / cg"
 !
 
 readDecimalFractionFrom:aStringOrStream onError:exceptionBlock