SmallInteger.st
changeset 3135 8c0f47cf59e3
parent 3131 8170f7412e90
child 3156 3d63afe752e5
equal deleted inserted replaced
3134:22c7071ff004 3135:8c0f47cf59e3
   422 
   422 
   423     INT me, t, val;
   423     INT me, t, val;
   424     double dval;
   424     double dval;
   425 
   425 
   426     if (__isSmallInteger(aNumber)) {
   426     if (__isSmallInteger(aNumber)) {
   427 	val = __intVal(aNumber);
   427         val = __intVal(aNumber);
   428 	if (val != 0) {
   428         if (val != 0) {
   429 	    me = __intVal(self);
   429             me = __intVal(self);
   430 	    t = me / val;
   430             t = me / val;
   431 #ifdef GOOD_OPTIMIZER
   431 #ifdef GOOD_OPTIMIZER
   432 	    if (me % val) {
   432             if (me % val) {
   433 #else
   433 #else
   434 	    /* this is stupid - all I want is to look for a remainder ... 
   434             /* this is stupid - all I want is to look for a remainder ... 
   435 	       but most compilers are too stupid and generate an extra modulu
   435                but most compilers are too stupid and generate an extra modulus
   436 	       instruction for "if (me % val)".
   436                instruction for "if (me % val)".
   437 	       Even if most divide instructions already leave the remainder in
   437                Even if most divide instructions already leave the remainder in
   438 	       some register.
   438                some register.
   439 	       Therefore I use a multiplication which is faster than a modulu
   439                Therefore I use a multiplication which is faster than a modulo
   440 	       on most machines. Hint to GNU people :-)
   440                on most machines. Hint to GNU people :-)
   441 	    */
   441             */
   442 	    if ((t * val) == me) {
   442             if ((t * val) == me) {
   443 #endif
   443 #endif
   444 		RETURN ( __MKSMALLINT(t) );
   444                 RETURN ( __MKSMALLINT(t) );
   445 	    }
   445             }
   446 	}
   446         }
   447     } else {
   447     } else {
   448 	if (__isFloatLike(aNumber)) {
   448         if (__isFloatLike(aNumber)) {
   449 	    dval = __floatVal(aNumber);
   449             dval = __floatVal(aNumber);
   450 	    if (dval != 0.0) {
   450             if (dval != 0.0) {
   451 		OBJ newFloat;
   451                 OBJ newFloat;
   452 		double val = (double)__intVal(self) / dval;
   452                 double val = (double)__intVal(self) / dval;
   453 
   453 
   454 		__qMKFLOAT(newFloat, val);
   454                 __qMKFLOAT(newFloat, val);
   455 		RETURN ( newFloat );
   455                 RETURN ( newFloat );
   456 	    }
   456             }
   457 	}
   457         }
   458     }
   458     }
   459 %}.
   459 %}.
   460     aNumber isInteger ifTrue:[
   460     aNumber isInteger ifTrue:[
   461 	aNumber == 0 ifTrue:[
   461         aNumber == 0 ifTrue:[
   462 	    ^ DivisionByZeroSignal raise.
   462             ^ DivisionByZeroSignal raise.
   463 	].
   463         ].
   464 	^ Fraction numerator:self denominator:aNumber
   464         ^ Fraction numerator:self denominator:aNumber
   465     ].
   465     ].
   466     ^ aNumber quotientFromInteger:self
   466     ^ aNumber quotientFromInteger:self
   467 
   467 
   468     "
   468     "
   469      8 / 4
   469      8 / 4
  2203                 selfInt = ttt;
  2203                 selfInt = ttt;
  2204                 ttt = temp;
  2204                 ttt = temp;
  2205             }
  2205             }
  2206             /*
  2206             /*
  2207              * since its not defined in C, what the sign of
  2207              * since its not defined in C, what the sign of
  2208              * a modulu result is when the arg is negative,
  2208              * a modulus result is when the arg is negative,
  2209              * change it explicitely here ...
  2209              * change it explicitely here ...
  2210              */
  2210              */
  2211             if (orgArg < 0) {
  2211             if (orgArg < 0) {
  2212                 /* result should be negative */
  2212                 /* result should be negative */
  2213                 if (orgSelfInt > 0) selfInt = -selfInt;
  2213                 if (orgSelfInt > 0) selfInt = -selfInt;
  2251     self < 100000000 ifTrue:[^ 8].
  2251     self < 100000000 ifTrue:[^ 8].
  2252     self < 1000000000 ifTrue:[^ 9].
  2252     self < 1000000000 ifTrue:[^ 9].
  2253     ^ 10
  2253     ^ 10
  2254 ! !
  2254 ! !
  2255 
  2255 
  2256 !SmallInteger methodsFor:'modulu arithmetic'!
  2256 !SmallInteger methodsFor:'modulo arithmetic'!
  2257 
  2257 
  2258 plus:aNumber
  2258 plus:aNumber
  2259     "return the sum of the receiver and the argument, as SmallInteger.
  2259     "return the sum of the receiver and the argument, as SmallInteger.
  2260      The argument must be another SmallInteger.
  2260      The argument must be another SmallInteger.
  2261      If the result overflows the smallInteger range, the value modulu the 
  2261      If the result overflows the smallInteger range, the value modulo the 
  2262      smallInteger range is returned (i.e. the low bits of the sum).
  2262      smallInteger range is returned (i.e. the low bits of the sum).
  2263      This is of course not always correct, but some code does a modulu anyway
  2263      This is of course not always correct, but some code does a modulo anyway
  2264      and can therefore speed things up by not going through LargeIntegers."
  2264      and can therefore speed things up by not going through LargeIntegers."
  2265 
  2265 
  2266 %{  /* NOCONTEXT */
  2266 %{  /* NOCONTEXT */
  2267 
  2267 
  2268     if (__isSmallInteger(aNumber)) {
  2268     if (__isSmallInteger(aNumber)) {
  2269 	INT sum;
  2269         INT sum;
  2270 
  2270 
  2271 	sum = __intVal(self) + __intVal(aNumber);
  2271         sum = __intVal(self) + __intVal(aNumber);
  2272 #ifdef alpha64
  2272 #ifdef alpha64
  2273 	sum &= 0x7FFFFFFFFFFFFFFFL;
  2273         sum &= 0x7FFFFFFFFFFFFFFFL;
  2274 #else
  2274 #else
  2275 	sum &= 0x7FFFFFFF;
  2275         sum &= 0x7FFFFFFF;
  2276 #endif
  2276 #endif
  2277 	RETURN ( __MKSMALLINT(sum));
  2277         RETURN ( __MKSMALLINT(sum));
  2278     }
  2278     }
  2279 %}.
  2279 %}.
  2280     self primitiveFailed
  2280     self primitiveFailed
  2281 !
  2281 !
  2282 
  2282 
  2283 subtract:aNumber
  2283 subtract:aNumber
  2284     "return the difference of the receiver and the argument, as SmallInteger.
  2284     "return the difference of the receiver and the argument, as SmallInteger.
  2285      The argument must be another SmallInteger.
  2285      The argument must be another SmallInteger.
  2286      If the result overflows the smallInteger range, the value modulu the 
  2286      If the result overflows the smallInteger range, the value modulo the 
  2287      smallInteger range is returned (i.e. the low bits of the sum).
  2287      smallInteger range is returned (i.e. the low bits of the sum).
  2288      This is of course not always correct, but some code does a modulu anyway
  2288      This is of course not always correct, but some code does a modulo anyway
  2289      and can therefore speed things up by not going through LargeIntegers."
  2289      and can therefore speed things up by not going through LargeIntegers."
  2290 
  2290 
  2291 %{  /* NOCONTEXT */
  2291 %{  /* NOCONTEXT */
  2292 
  2292 
  2293     if (__isSmallInteger(aNumber)) {
  2293     if (__isSmallInteger(aNumber)) {
  2294 	INT diff;
  2294         INT diff;
  2295 
  2295 
  2296 	diff = __intVal(self) - __intVal(aNumber);
  2296         diff = __intVal(self) - __intVal(aNumber);
  2297 #ifdef alpha64
  2297 #ifdef alpha64
  2298 	diff &= 0x7FFFFFFFFFFFFFFFL;
  2298         diff &= 0x7FFFFFFFFFFFFFFFL;
  2299 #else
  2299 #else
  2300 	diff &= 0x7FFFFFFF;
  2300         diff &= 0x7FFFFFFF;
  2301 #endif
  2301 #endif
  2302 	RETURN ( __MKSMALLINT(diff));
  2302         RETURN ( __MKSMALLINT(diff));
  2303     }
  2303     }
  2304 %}.
  2304 %}.
  2305     self primitiveFailed
  2305     self primitiveFailed
  2306 !
  2306 !
  2307 
  2307 
  2308 times:aNumber
  2308 times:aNumber
  2309     "return the product of the receiver and the argument, as SmallInteger.
  2309     "return the product of the receiver and the argument, as SmallInteger.
  2310      The argument must be another SmallInteger.
  2310      The argument must be another SmallInteger.
  2311      If the result overflows the smallInteger range, the value modulu the 
  2311      If the result overflows the smallInteger range, the value modulo the 
  2312      smallInteger range is returned (i.e. the low bits of the product).
  2312      smallInteger range is returned (i.e. the low bits of the product).
  2313      This is of course not always correct, but some code does a modulu anyway
  2313      This is of course not always correct, but some code does a modulo anyway
  2314      and can therefore speed things up by not going through LargeIntegers."
  2314      and can therefore speed things up by not going through LargeIntegers."
  2315 
  2315 
  2316 %{  /* NOCONTEXT */
  2316 %{  /* NOCONTEXT */
  2317 
  2317 
  2318     if (__isSmallInteger(aNumber)) {
  2318     if (__isSmallInteger(aNumber)) {
  2319 	INT prod;
  2319         INT prod;
  2320 
  2320 
  2321 	prod = __intVal(self) * __intVal(aNumber);
  2321         prod = __intVal(self) * __intVal(aNumber);
  2322 #ifdef alpha64
  2322 #ifdef alpha64
  2323 	prod &= 0x7FFFFFFFFFFFFFFFL;
  2323         prod &= 0x7FFFFFFFFFFFFFFFL;
  2324 #else
  2324 #else
  2325 	prod &= 0x7FFFFFFF;
  2325         prod &= 0x7FFFFFFF;
  2326 #endif
  2326 #endif
  2327 	RETURN ( __MKSMALLINT(prod));
  2327         RETURN ( __MKSMALLINT(prod));
  2328     }
  2328     }
  2329 %}.
  2329 %}.
  2330     self primitiveFailed
  2330     self primitiveFailed
  2331 ! !
  2331 ! !
  2332 
  2332 
  2624 ! !
  2624 ! !
  2625 
  2625 
  2626 !SmallInteger class methodsFor:'documentation'!
  2626 !SmallInteger class methodsFor:'documentation'!
  2627 
  2627 
  2628 version
  2628 version
  2629     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.90 1997-12-17 21:20:10 cg Exp $'
  2629     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.91 1997-12-19 08:38:23 stefan Exp $'
  2630 ! !
  2630 ! !