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 |
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 |