1288 TestCase assert:( 16r80000000 setBit:3 ) = 16r80000004 |
1288 TestCase assert:( 16r80000000 setBit:3 ) = 16r80000004 |
1289 TestCase assert:( 16r80000000 setBit:33 ) = 16r180000000 |
1289 TestCase assert:( 16r80000000 setBit:33 ) = 16r180000000 |
1290 " |
1290 " |
1291 ! ! |
1291 ! ! |
1292 |
1292 |
|
1293 !LargeInteger methodsFor:'bit operators-32bit'! |
|
1294 |
|
1295 bitInvert32 |
|
1296 "return the value of the receiver with all bits inverted in 32bit signed int space |
|
1297 (changes the sign)" |
|
1298 |
|
1299 %{ /* NOCONTEXT */ |
|
1300 unsigned INT v; |
|
1301 |
|
1302 v = __unsignedLongIntVal(self); |
|
1303 v = ~v; |
|
1304 #if __POINTER_SIZE__ == 8 |
|
1305 v &= 0xFFFFFFFFL; |
|
1306 #endif |
|
1307 RETURN ( __MKUINT(v) ); |
|
1308 %}. |
|
1309 ^ self primitiveFailed |
|
1310 |
|
1311 " |
|
1312 16r80000000 bitInvert32 hexPrintString |
|
1313 16r7FFFFFFF bitInvert32 hexPrintString |
|
1314 16rFFFFFFFF bitInvert32 hexPrintString |
|
1315 0 bitInvert32 hexPrintString |
|
1316 " |
|
1317 ! |
|
1318 |
|
1319 bitRotate32:shiftCount |
|
1320 "return the value of the receiver rotated by shiftCount bits, |
|
1321 but only within 32 bits, rotating left for positive, right for negative counts. |
|
1322 Rotates through the sign bit. |
|
1323 Useful for crypt algorithms, or to emulate C/Java semantics." |
|
1324 |
|
1325 %{ /* NOCONTEXT */ |
|
1326 |
|
1327 unsigned INT bits; |
|
1328 int count; |
|
1329 |
|
1330 if (__isSmallInteger(shiftCount)) { |
|
1331 count = __intVal(shiftCount); |
|
1332 count = count % 32; |
|
1333 |
|
1334 bits = __unsignedLongIntVal(self); |
|
1335 if (count > 0) { |
|
1336 bits = (bits << count) | (bits >> (32-count)); |
|
1337 } else { |
|
1338 bits = (bits >> (-count)) | (bits << (32-(-count))); |
|
1339 } |
|
1340 #if __POINTER_SIZE__ == 8 |
|
1341 bits &= 0xFFFFFFFFL; |
|
1342 #endif |
|
1343 RETURN (__MKUINT(bits)); |
|
1344 } |
|
1345 %}. |
|
1346 ^ self primitiveFailed |
|
1347 |
|
1348 " |
|
1349 (1 bitShift32:31) rotate32:0 |
|
1350 (1 bitShift32:31) rotate32:1 |
|
1351 (1 bitShift32:31) rotate32:-1 |
|
1352 " |
|
1353 ! |
|
1354 |
|
1355 bitShift32:shiftCount |
|
1356 "return the value of the receiver shifted by shiftCount bits, |
|
1357 but only within 32 bits, shifting into/out-of the sign bit. |
|
1358 May be useful for communication interfaces, to create ST-numbers |
|
1359 from a signed 32bit int value given as individual bytes, |
|
1360 or to emulate C/Java semantics. |
|
1361 The shift is unsigned" |
|
1362 |
|
1363 %{ /* NOCONTEXT */ |
|
1364 |
|
1365 unsigned INT bits; |
|
1366 int count; |
|
1367 |
|
1368 if (__isSmallInteger(shiftCount)) { |
|
1369 count = __intVal(shiftCount); |
|
1370 if (count >= 32) { |
|
1371 RETURN (__mkSmallInteger(0)); |
|
1372 } |
|
1373 |
|
1374 bits = __unsignedLongIntVal(self); |
|
1375 if (count > 0) { |
|
1376 bits = bits << count; |
|
1377 } else { |
|
1378 bits = bits >> (-count); |
|
1379 } |
|
1380 #if __POINTER_SIZE__ == 8 |
|
1381 bits &= 0xFFFFFFFFL; |
|
1382 #endif |
|
1383 RETURN (__MKUINT(bits)); |
|
1384 } |
|
1385 %}. |
|
1386 ^ self primitiveFailed |
|
1387 |
|
1388 " |
|
1389 128 bitShift:24 |
|
1390 128 bitShift32:24 |
|
1391 |
|
1392 1 bitShift:31 |
|
1393 1 bitShift32:31 |
|
1394 " |
|
1395 ! |
|
1396 |
|
1397 bitXor32:aNumber |
|
1398 "return the xor of the receiver and the argument. |
|
1399 The argument must be a SmallInteger or a 4-byte LargeInteger. |
|
1400 If the result overflows the 32 bit range, the value modulo 16rFFFFFFFF is returned. |
|
1401 This is of course not always correct, but allows for C/Java behavior to be emulated." |
|
1402 |
|
1403 %{ /* NOCONTEXT */ |
|
1404 INT rslt; |
|
1405 |
|
1406 rslt = __unsignedLongIntVal(self) ^ __unsignedLongIntVal(aNumber); |
|
1407 #if __POINTER_SIZE__ == 8 |
|
1408 rslt &= 0xFFFFFFFFL; |
|
1409 #endif |
|
1410 RETURN ( __MKUINT(rslt)); |
|
1411 %}. |
|
1412 self primitiveFailed |
|
1413 |
|
1414 " |
|
1415 16r7FFFFFFF bitXor: 16r80000000 4294967295 |
|
1416 16r7FFFFFFF bitXor32: 16r80000000 |
|
1417 " |
|
1418 ! ! |
|
1419 |
1293 !LargeInteger methodsFor:'byte access'! |
1420 !LargeInteger methodsFor:'byte access'! |
1294 |
1421 |
1295 digitAt:index |
1422 digitAt:index |
1296 "return 8 bits of value, starting at byte index" |
1423 "return 8 bits of value, starting at byte index" |
1297 |
1424 |
1393 |
1520 |
1394 asLargeInteger |
1521 asLargeInteger |
1395 "return a LargeInteger with same value as myself - thats me" |
1522 "return a LargeInteger with same value as myself - thats me" |
1396 |
1523 |
1397 ^ self |
1524 ^ self |
|
1525 ! |
|
1526 |
|
1527 asSigned32 |
|
1528 "return a 32-bit integer with my bit-pattern. Receiver must be unsigned (i.e. positive). |
|
1529 May be required for bit operations on the sign-bit and/or to |
|
1530 convert C/Java numbers." |
|
1531 |
|
1532 %{ /* NOCONTEXT */ |
|
1533 int rslt; |
|
1534 |
|
1535 rslt = (int)(__unsignedLongIntVal(self)); |
|
1536 RETURN ( __MKINT(rslt)); |
|
1537 %}. |
|
1538 self primitiveFailed |
|
1539 |
|
1540 " |
|
1541 16r80000000 asSigned32 |
|
1542 16r40000000 asSigned32 |
|
1543 " |
1398 ! |
1544 ! |
1399 |
1545 |
1400 asSmallInteger |
1546 asSmallInteger |
1401 "return a SmallInteger with same value as myself - |
1547 "return a SmallInteger with same value as myself - |
1402 the result is invalid if the receivers value cannot |
1548 the result is invalid if the receivers value cannot |
2287 " |
2452 " |
2288 |
2453 |
2289 "Modified: / 9.1.1998 / 13:27:37 / cg" |
2454 "Modified: / 9.1.1998 / 13:27:37 / cg" |
2290 ! ! |
2455 ! ! |
2291 |
2456 |
|
2457 !LargeInteger methodsFor:'modulu arithmetic'! |
|
2458 |
|
2459 plus32:aNumber |
|
2460 "return the sum of the receiver and the argument, as SmallInteger. |
|
2461 The argument must be another SmallInteger. |
|
2462 If the result overflows the 32 bit range, the value modulo 16rFFFFFFFF is returned. |
|
2463 This is of course not always correct, but allows for C/Java behavior to be emulated." |
|
2464 |
|
2465 %{ /* NOCONTEXT */ |
|
2466 INT sum; |
|
2467 |
|
2468 sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aNumber); |
|
2469 #if __POINTER_SIZE__ == 8 |
|
2470 sum &= 0xFFFFFFFFL; |
|
2471 #endif |
|
2472 RETURN ( __MKUINT(sum)); |
|
2473 %}. |
|
2474 self primitiveFailed |
|
2475 |
|
2476 " |
|
2477 16r7FFFFFFF + 1 -> 2147483648 |
|
2478 16r7FFFFFFF plus32: 1 -> -2147483648 |
|
2479 " |
|
2480 ! ! |
|
2481 |
2292 !LargeInteger methodsFor:'printing & storing'! |
2482 !LargeInteger methodsFor:'printing & storing'! |
2293 |
2483 |
2294 xxxstoreOn:aStream |
2484 xxxstoreOn:aStream |
2295 "append a representation of the receiver to aStream, which can |
2485 "append a representation of the receiver to aStream, which can |
2296 be used to reconstruct the receiver." |
2486 be used to reconstruct the receiver." |
2367 d1 "{ Class: SmallInteger }" |
2557 d1 "{ Class: SmallInteger }" |
2368 d2 "{ Class: SmallInteger }" |
2558 d2 "{ Class: SmallInteger }" |
2369 otherDigitByteArray | |
2559 otherDigitByteArray | |
2370 |
2560 |
2371 %{ /* NOCONTEXT */ |
2561 %{ /* NOCONTEXT */ |
2372 OBJ _digitByteArray = __INST(digitByteArray); |
|
2373 |
|
2374 if (__isLargeInteger(aLargeInteger)) { |
2562 if (__isLargeInteger(aLargeInteger)) { |
|
2563 OBJ _digitByteArray = __INST(digitByteArray); |
2375 OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits; |
2564 OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits; |
2376 |
2565 |
2377 if (__isByteArray(_digitByteArray) |
2566 if (__isByteArray(_digitByteArray) |
2378 && __isByteArray(_otherDigitByteArray)) { |
2567 && __isByteArray(_otherDigitByteArray)) { |
2379 INT _myLen = __byteArraySize(_digitByteArray); |
2568 INT _myLen = __byteArraySize(_digitByteArray); |
2383 unsigned char *_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
2572 unsigned char *_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element; |
2384 |
2573 |
2385 if (_myLen == _otherLen) { |
2574 if (_myLen == _otherLen) { |
2386 tryAgain: |
2575 tryAgain: |
2387 while (_myLen >= (sizeof(INT)*4)) { |
2576 while (_myLen >= (sizeof(INT)*4)) { |
2388 if ( (unsigned INT *)_myDigits[0] != (unsigned INT *)_otherDigits[0]) { |
2577 if ( ((unsigned INT *)_myDigits)[0] != ((unsigned INT *)_otherDigits)[0]) { |
2389 RETURN(false); |
2578 RETURN(false); |
2390 } |
2579 } |
2391 if ( (unsigned INT *)_myDigits[1] != (unsigned INT *)_otherDigits[1]) { |
2580 if ( ((unsigned INT *)_myDigits)[1] != ((unsigned INT *)_otherDigits)[1]) { |
2392 RETURN(false); |
2581 RETURN(false); |
2393 } |
2582 } |
2394 if ( (unsigned INT *)_myDigits[2] != (unsigned INT *)_otherDigits[2]) { |
2583 if ( ((unsigned INT *)_myDigits)[2] != ((unsigned INT *)_otherDigits)[2]) { |
2395 RETURN(false); |
2584 RETURN(false); |
2396 } |
2585 } |
2397 if ( (unsigned INT *)_myDigits[3] != (unsigned INT *)_otherDigits[3]) { |
2586 if ( ((unsigned INT *)_myDigits)[3] != ((unsigned INT *)_otherDigits)[3]) { |
2398 RETURN(false); |
2587 RETURN(false); |
2399 } |
2588 } |
2400 _myDigits += sizeof(INT)*4; |
2589 _myDigits += sizeof(INT)*4; |
2401 _otherDigits += sizeof(INT)*4; |
2590 _otherDigits += sizeof(INT)*4; |
2402 _myLen -= sizeof(INT)*4; |
2591 _myLen -= sizeof(INT)*4; |