--- a/SmallInteger.st Thu Mar 10 15:25:36 2016 +0100
+++ b/SmallInteger.st Thu Mar 10 15:59:13 2016 +0100
@@ -1401,9 +1401,9 @@
"return the value of the receiver shifted by shiftCount bits;
leftShift if shiftCount > 0; rightShift otherwise.
Notice: the result of bitShift: on negative receivers is not
- defined in the language standard (since the implementation
- is free to choose any internal representation for integers).
- However, ST/X preserves the sign."
+ defined in the language standard (since the implementation
+ is free to choose any internal representation for integers).
+ However, ST/X preserves the sign."
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
@@ -1412,68 +1412,80 @@
INT bits, count;
if (__isSmallInteger(shiftCount)) {
- bits = __intVal(self);
- if (bits == 0) {
- RETURN (self);
- }
-
- count = __intVal(shiftCount);
-
- if (count > 0) {
- /*
- * a left shift
- */
+ bits = __intVal(self);
+ if (bits == 0) {
+ RETURN (self);
+ }
+ count = __intVal(shiftCount);
+
+ if (count > 0) {
+ INT sign = 1;
+ if (bits < 0) {
+ bits = -bits;
+ sign = -1;
+ }
+ /*
+ * a left shift
+ */
# if defined(USE_LONGLONG_FOR_SHIFT)
- if (count <= N_INT_BITS) {
- unsigned LONGLONG result;
-
- result = (unsigned LONGLONG)bits;
- result <<= count;
- if (result <= _MAX_INT) {
- RETURN ( __mkSmallInteger(result) );
- }
- {
- RETURN (__MKLARGEINT64(1, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
- }
- }
+ if (count <= N_INT_BITS) {
+ unsigned LONGLONG result;
+
+ result = (unsigned LONGLONG)bits;
+ result <<= count;
+ if (result <= _MAX_INT) {
+ if (sign < 0) {
+ RETURN ( __MKINT(-result) );
+ }
+ RETURN ( __mkSmallInteger(result) );
+ }
+ {
+ RETURN (__MKLARGEINT64(sign, (INT)(result >> 32), (INT)(result & 0xFFFFFFFF)));
+ }
+ }
# else
- /*
- * check for overflow
- */
- if (count < (N_INT_BITS-1)) {
- if (! (bits >> (N_INT_BITS - 1 - count))) {
- RETURN ( __mkSmallInteger(bits << count) );
- }
- /*
- * so, there is an overflow ...
- * handle it as largeInteger
- */
- /* FALL THROUGH */
- }
+ /*
+ * check for overflow
+ */
+ if (count < (N_INT_BITS-1)) {
+ if (! (bits >> (N_INT_BITS - 1 - count))) {
+ INT result = bits << count;
+
+ if (sign < 0) {
+ RETURN ( __MKINT(-result) );
+ }
+ RETURN ( __mkSmallInteger(result) );
+ }
+ /*
+ * so, there is an overflow ...
+ * handle it as largeInteger
+ */
+ /* FALL THROUGH */
+ }
# endif
- } else {
- if (count == 0) {
- RETURN (self);
- }
-
- /*
- * right shifts cannot overflow
- *
- * some machines ignore shifts bigger than
- * the number of bits in an int ...
- */
- count = -count;
- if (count > (N_INT_BITS-1)) {
- RETURN (__mkSmallInteger(0));
- }
-
- RETURN ( __mkSmallInteger(bits >> count) );
- }
+ } else {
+ if (count == 0) {
+ RETURN (self);
+ }
+
+ /*
+ * right shifts cannot overflow
+ *
+ * some machines ignore shifts bigger than
+ * the number of bits in an int ...
+ */
+ count = -count;
+ if (count > (N_INT_BITS-1)) {
+ RETURN (__mkSmallInteger(0));
+ }
+
+ RETURN ( __mkSmallInteger(bits >> count) );
+ }
}
#endif /* not __SCHTEAM__ */
%}.
(shiftCount isMemberOf:SmallInteger) ifTrue:[
- ^ (LargeInteger value:self) bitShift:shiftCount
+ ^ (LargeInteger value:self) bitShift:shiftCount
].
^ self bitShift:shiftCount asInteger "/ is this a good idea ?
!