Fraction.st
branchjv
changeset 19277 e9182dc00c6d
parent 19250 a93b96b49985
parent 19261 02cb0c66a1b8
child 20344 152b525b5c63
equal deleted inserted replaced
19250:a93b96b49985 19277:e9182dc00c6d
       
     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 iDen;
   101 		    INT iDen;
   103                     INT iNum;
   102 
   104 
   103 		    __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
   105                     __qCheckedAlignedNew(newFraction, sizeof(struct __Fraction));
   104 		    __InstPtr(newFraction)->o_class = self;
   106                     __InstPtr(newFraction)->o_class = self;
   105 		    __qSTORE(newFraction, self);
   107                     __qSTORE(newFraction, self);
   106 		    iDen = __intVal(den);
   108 
   107 		    if (iDen != 0) {
   109                     iDen = __intVal(den);
   108 			if (iDen < 0) {
   110                     iNum = __intVal(num);
   109 			    __FractionInstPtr(newFraction)->f_numerator = __mkSmallInteger(- __intVal(num));
   111 
   110 			    __FractionInstPtr(newFraction)->f_denominator = __mkSmallInteger(- iDen);
   112                     if (iDen < 0) {
   111 			} else {
   113                         iNum = -iNum;
   112 			    __FractionInstPtr(newFraction)->f_numerator = num;
   114                         iDen = -iDen;
   113 			    __FractionInstPtr(newFraction)->f_denominator = den;
   115                     }
   114 			}
   116                     while ( (((iNum | iDen) & 1) == 0) && ( iNum != 0) && ( iDen != 0)) {
   115 			if (num == __mkSmallInteger(1)) {
   117                         /* both even and non-zero */
   116 			    /* no need to reduce */
   118                         iNum = iNum >> 1;
   117 			    RETURN ( newFraction );
   119                         iDen = iDen >> 1;
   118 			}
   120                     }
   119 		    }
   121                     if (iNum >= _MAX_INT) {
   120 		}
   122                         __FractionInstPtr(newFraction)->f_numerator = __MKINT(iNum);
   121 	    }
   123                     } else {
   122 	}
   124                         __FractionInstPtr(newFraction)->f_numerator = __MKSMALLINT(iNum);
       
   125                     }
       
   126                     if (iDen >= _MAX_INT) {
       
   127                         __FractionInstPtr(newFraction)->f_denominator = __MKINT(iDen);
       
   128                     } else {
       
   129                         __FractionInstPtr(newFraction)->f_denominator = __MKSMALLINT(iDen);
       
   130                     }
       
   131                     if (iNum == 1) {
       
   132                         /* no need to reduce */
       
   133                         RETURN ( newFraction );
       
   134                     }
       
   135                 }
       
   136             }
       
   137         }
   123     }
   138     }
   124 #endif /* not __SCHTEAM__ */
   139 #endif /* not __SCHTEAM__ */
   125 %}.
   140 %}.
   126     den = 0 ifTrue:[
   141     den = 0 ifTrue:[
   127 	^ ZeroDivide raiseRequestWith:thisContext.
   142         ^ ZeroDivide raiseRequestWith:thisContext.
   128     ].
   143     ].
   129     newFraction isNil ifTrue:[
   144     newFraction isNil ifTrue:[
   130 	newFraction := self basicNew setNumerator:num denominator:den.
   145         newFraction := self basicNew setNumerator:num denominator:den.
   131     ].
   146     ].
   132     ^ newFraction reduced
   147     ^ newFraction reduced
   133 
   148 
   134     "
   149     "
   135      Fraction numerator:1 denominator:3
   150      Fraction numerator:1 denominator:3 
   136      Fraction numerator:2 denominator:6
   151      Fraction numerator:2 denominator:3   
   137 
   152      Fraction numerator:2 denominator:6 
   138      Fraction numerator:1 denominator:0
   153 
   139      Fraction numerator:2 denominator:0
   154      Fraction numerator:1 denominator:0  -> error
   140     "
   155      Fraction numerator:2 denominator:0  -> error
       
   156 
       
   157      Fraction numerator:5 denominator:10    
       
   158      Fraction numerator:50 denominator:100  
       
   159      Fraction numerator:8 denominator:16  
       
   160     "
       
   161 
       
   162     "Modified: / 27-02-2016 / 00:25:47 / cg"
   141 !
   163 !
   142 
   164 
   143 readDecimalFractionFrom:aStringOrStream onError:exceptionBlock
   165 readDecimalFractionFrom:aStringOrStream onError:exceptionBlock
   144     "Read an arbitrary number (>0) of digits representing a decimal fraction."
   166     "Read an arbitrary number (>0) of digits representing a decimal fraction."
   145 
   167