Fraction.st
changeset 19259 9e95248432bd
parent 19248 a34488b9f1e6
child 19261 02cb0c66a1b8
equal deleted inserted replaced
19258:2653727e407a 19259:9e95248432bd
       
     1 "{ Encoding: utf8 }"
       
     2 
     1 "
     3 "
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     4  COPYRIGHT (c) 1989 by Claus Gittinger
     3 	      All Rights Reserved
     5 	      All Rights Reserved
     4 
     6 
     5  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
    86     |newFraction|
    88     |newFraction|
    87 
    89 
    88 %{  /* NOCONTEXT */
    90 %{  /* NOCONTEXT */
    89 #ifdef __SCHTEAM__
    91 #ifdef __SCHTEAM__
    90     if (self == Fraction.Class) {
    92     if (self == Fraction.Class) {
    91 	return context._RETURN(new STFraction(num, den));
    93         return context._RETURN(new STFraction(num, den));
    92     }
    94     }
    93 #else
    95 #else
    94     /* this check allows subclassing .. */
    96     /* this check allows subclassing .. */
    95     if (self == Fraction) {
    97     if (self == Fraction) {
    96 	if (__bothSmallInteger(num, den)) {
    98         if (__bothSmallInteger(num, den)) {
    97 	    if (den != __mkSmallInteger(0)) {
    99             if (den != __mkSmallInteger(0)) {
    98 		if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) {    /* OBJECT ALLOCATION */
   100                 if (__CanDoQuickAlignedNew(sizeof(struct __Fraction))) {    /* OBJECT ALLOCATION */
    99 		    OBJ newFraction;
   101                     OBJ newFraction;
   100 		    int spc;
   102                     int spc;
   101 		    INT iDen;
   103                     INT iDen;
   102 
   104                     INT iNum;
   103 		    __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
   105 
   104 		    __InstPtr(newFraction)->o_class = self;
   106                     __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
   105 		    __qSTORE(newFraction, self);
   107                     __InstPtr(newFraction)->o_class = self;
   106 		    iDen = __intVal(den);
   108                     __qSTORE(newFraction, self);
   107 		    if (iDen != 0) {
   109 
   108 			if (iDen < 0) {
   110                     iDen = __intVal(den);
   109 			    __FractionInstPtr(newFraction)->f_numerator = __mkSmallInteger(- __intVal(num));
   111                     iNum = __intVal(num);
   110 			    __FractionInstPtr(newFraction)->f_denominator = __mkSmallInteger(- iDen);
   112 
   111 			} else {
   113                     if (iDen < 0) {
   112 			    __FractionInstPtr(newFraction)->f_numerator = num;
   114                         iNum = -iNum;
   113 			    __FractionInstPtr(newFraction)->f_denominator = den;
   115                         iDen = -iDen;
   114 			}
   116                     }
   115 			if (num == __mkSmallInteger(1)) {
   117                     while ( (((iNum | iDen) & 1) == 0) && ( iNum != 0) && ( iDen != 0)) {
   116 			    /* no need to reduce */
   118                         /* both even and non-zero */
   117 			    RETURN ( newFraction );
   119                         iNum = iNum >> 1;
   118 			}
   120                         iDen = iDen >> 1;
   119 		    }
   121                     }
   120 		}
   122                     if (iNum >= _MAX_INT) {
   121 	    }
   123                         __FractionInstPtr(newFraction)->f_numerator = __MKINT(iNum);
   122 	}
   124                     } else {
       
   125                         __FractionInstPtr(newFraction)->f_numerator = __MKSMALLINT(iNum);
       
   126                     }
       
   127                     if (iDen >= _MAX_INT) {
       
   128                         __FractionInstPtr(newFraction)->f_denominator = __MKINT(iDen);
       
   129                     } else {
       
   130                         __FractionInstPtr(newFraction)->f_denominator = __MKSMALLINT(iDen);
       
   131                     }
       
   132                     if (iNum == 1) {
       
   133                         /* no need to reduce */
       
   134                         RETURN ( newFraction );
       
   135                     }
       
   136                 }
       
   137             }
       
   138         }
   123     }
   139     }
   124 #endif /* not __SCHTEAM__ */
   140 #endif /* not __SCHTEAM__ */
   125 %}.
   141 %}.
   126     den = 0 ifTrue:[
   142     den = 0 ifTrue:[
   127 	^ ZeroDivide raiseRequestWith:thisContext.
   143         ^ ZeroDivide raiseRequestWith:thisContext.
   128     ].
   144     ].
   129     newFraction isNil ifTrue:[
   145     newFraction isNil ifTrue:[
   130 	newFraction := self basicNew setNumerator:num denominator:den.
   146         newFraction := self basicNew setNumerator:num denominator:den.
   131     ].
   147     ].
   132     ^ newFraction reduced
   148     ^ newFraction reduced
   133 
   149 
   134     "
   150     "
   135      Fraction numerator:1 denominator:3
   151      Fraction numerator:1 denominator:3 
   136      Fraction numerator:2 denominator:6
   152      Fraction numerator:2 denominator:3   
   137 
   153      Fraction numerator:2 denominator:6 
   138      Fraction numerator:1 denominator:0
   154 
   139      Fraction numerator:2 denominator:0
   155      Fraction numerator:1 denominator:0  -> error
   140     "
   156      Fraction numerator:2 denominator:0  -> error
       
   157 
       
   158      Fraction numerator:5 denominator:10    
       
   159      Fraction numerator:50 denominator:100  
       
   160      Fraction numerator:8 denominator:16  
       
   161     "
       
   162 
       
   163     "Modified: / 26-02-2016 / 21:52:05 / cg"
   141 !
   164 !
   142 
   165 
   143 readDecimalFractionFrom:aStringOrStream onError:exceptionBlock
   166 readDecimalFractionFrom:aStringOrStream onError:exceptionBlock
   144     "Read an arbitrary number (>0) of digits representing a decimal fraction."
   167     "Read an arbitrary number (>0) of digits representing a decimal fraction."
   145 
   168