LargeInteger.st
branchjv
changeset 17763 019bb9c842c5
parent 17761 b0e5971141bc
child 17767 a4a32df3aa5e
equal deleted inserted replaced
17762:6eb4414e6a31 17763:019bb9c842c5
  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
  1413 	(sign < 0) ifTrue:[
  1559 	(sign < 0) ifTrue:[
  1414 	    value := value negated
  1560 	    value := value negated
  1415 	]
  1561 	]
  1416     ].
  1562     ].
  1417     ^ value
  1563     ^ value
       
  1564 !
       
  1565 
       
  1566 asUnsigned32
       
  1567     "return a 32-bit integer with my bit-pattern. Receiver must be unsigned (i.e. positive).
       
  1568      May be required for bit operations on the sign-bit and/or to
       
  1569      convert C/Java numbers."
       
  1570 
       
  1571 %{  /* NOCONTEXT */
       
  1572     unsigned int rslt;
       
  1573 
       
  1574     rslt =  (int)(__unsignedLongIntVal(self));
       
  1575     RETURN ( __MKUINT(rslt));
       
  1576 %}.
       
  1577     self primitiveFailed
       
  1578 
       
  1579     "
       
  1580      16r80000000 asUnsigned32
       
  1581      16r40000000 asUnsigned32
       
  1582     "
  1418 !
  1583 !
  1419 
  1584 
  1420 coerce:aNumber
  1585 coerce:aNumber
  1421     "convert the argument aNumber into an instance of the receivers class and return it."
  1586     "convert the argument aNumber into an instance of the receivers class and return it."
  1422 
  1587 
  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;
  4948 ! !
  5137 ! !
  4949 
  5138 
  4950 !LargeInteger class methodsFor:'documentation'!
  5139 !LargeInteger class methodsFor:'documentation'!
  4951 
  5140 
  4952 version
  5141 version
  4953     ^ '$Id: LargeInteger.st 10517 2010-04-26 18:26:38Z vranyj1 $'
  5142     ^ '$Id: LargeInteger.st 10520 2010-05-04 11:50:05Z vranyj1 $'
  4954 !
  5143 !
  4955 
  5144 
  4956 version_CVS
  5145 version_CVS
  4957     ^ '§Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.199 2010/02/26 20:20:38 cg Exp §'
  5146     ^ 'Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.201 2010/04/14 08:00:14 stefan Exp §'
  4958 !
  5147 !
  4959 
  5148 
  4960 version_SVN
  5149 version_SVN
  4961     ^ '$Id: LargeInteger.st 10517 2010-04-26 18:26:38Z vranyj1 $'
  5150     ^ '$Id: LargeInteger.st 10520 2010-05-04 11:50:05Z vranyj1 $'
  4962 ! !
  5151 ! !
       
  5152