--- a/SmallInteger.st Sat Aug 13 06:52:18 2016 +0200
+++ b/SmallInteger.st Tue Aug 23 09:54:28 2016 +0100
@@ -621,12 +621,12 @@
The result is truncated toward negative infinity
and will be negative, if the operands signs differ.
The following is always true:
- (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
+ (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
Especially surprising:
- -1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
- -10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
+ -1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
+ -10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
See #quo: which returns -2 in the above case and #rem: which is the corresponding remainder."
@@ -648,95 +648,95 @@
INT dividend = __intVal(self);
if (__isSmallInteger(aNumber)) {
- divisor = __intVal(aNumber);
- if (divisor != 0) {
- rslt = dividend / divisor;
- /*
- * Optimized to speed up positive result
- */
- if (rslt <= 0) {
- if (rslt == 0) {
- if ((dividend ^ divisor) < 0) {
- /*
- * result (negative) has been truncated toward 0.
- * Return -1, because we truncate toward negative inf.
- */
- rslt = -1;
- }
- } else {
- /*
- * If result (negative) has been truncated toward 0,
- * subtract 1, because we truncate toward negative inf.
- */
- if (divisor > 0) {
- if (rslt * divisor > dividend) {
- rslt--;
- }
- } else {
- if (rslt * divisor < dividend) {
- rslt--;
- }
- }
- }
- }
- RETURN ( __mkSmallInteger(rslt) );
- }
+ divisor = __intVal(aNumber);
+ if (divisor != 0) {
+ rslt = dividend / divisor;
+ /*
+ * Optimized to speed up positive result
+ */
+ if (rslt <= 0) {
+ if (rslt == 0) {
+ if ((dividend ^ divisor) < 0) {
+ /*
+ * result (negative) has been truncated toward 0.
+ * Return -1, because we truncate toward negative inf.
+ */
+ rslt = -1;
+ }
+ } else {
+ /*
+ * If result (negative) has been truncated toward 0,
+ * subtract 1, because we truncate toward negative inf.
+ */
+ if (divisor > 0) {
+ if (rslt * divisor > dividend) {
+ rslt--;
+ }
+ } else {
+ if (rslt * divisor < dividend) {
+ rslt--;
+ }
+ }
+ }
+ }
+ RETURN ( __mkSmallInteger(rslt) );
+ }
} else {
- if (__isFractionLike(aNumber)) {
- OBJ t = __FractionInstPtr(aNumber)->f_numerator;
- if (__isSmallInteger(t)) {
- INT num = __intVal(t);
- t = __FractionInstPtr(aNumber)->f_denominator;
- if (__isSmallInteger(t)) {
- INT den = __intVal(t);
- INT prod;
+ if (__isFractionLike(aNumber)) {
+ OBJ t = __FractionInstPtr(aNumber)->f_numerator;
+ if (__isSmallInteger(t)) {
+ INT num = __intVal(t);
+ t = __FractionInstPtr(aNumber)->f_denominator;
+ if (__isSmallInteger(t)) {
+ INT den = __intVal(t);
+ INT prod;
#if 0 && defined(__GNUC__) // supported from GCC 5
- if (!__builtin_mul_overflow(myself, den, &prod)) {
- goto out; // overflow, try harder...
- }
+ if (!__builtin_mul_overflow(myself, den, &prod)) {
+ goto out; // overflow, try harder...
+ }
#else
- prod = dividend * den;
- // make sure, that no overflow occured
- if (prod / den != dividend) {
- goto out; // overflow, try harder...
- }
+ prod = dividend * den;
+ // make sure, that no overflow occurred
+ if (prod / den != dividend) {
+ goto out; // overflow, try harder...
+ }
#endif
- rslt = prod / num;
-
- /*
- * Optimized to speed up positive result
- */
- if (rslt <= 0) {
- if (rslt == 0) {
- if ((dividend ^ num) < 0) {
- /*
- * result (negative) has been truncated toward 0.
- * Return -1, because we truncate toward negative inf.
- */
- rslt = -1;
- }
- } else {
- /*
- * If result (negative) has been truncated toward 0,
- * subtract 1, because we truncate toward negative inf.
- */
- if (num > 0) {
- if (rslt * num > prod) rslt--;
- } else {
- if (rslt * num < prod) rslt--;
- }
- }
- }
- RETURN ( __mkSmallInteger(rslt) );
- }
- }
- }
+ rslt = prod / num;
+
+ /*
+ * Optimized to speed up positive result
+ */
+ if (rslt <= 0) {
+ if (rslt == 0) {
+ if ((dividend ^ num) < 0) {
+ /*
+ * result (negative) has been truncated toward 0.
+ * Return -1, because we truncate toward negative inf.
+ */
+ rslt = -1;
+ }
+ } else {
+ /*
+ * If result (negative) has been truncated toward 0,
+ * subtract 1, because we truncate toward negative inf.
+ */
+ if (num > 0) {
+ if (rslt * num > prod) rslt--;
+ } else {
+ if (rslt * num < prod) rslt--;
+ }
+ }
+ }
+ RETURN ( __mkSmallInteger(rslt) );
+ }
+ }
+ }
}
out:;
#endif /* not __SCHTEAM__ */
%}.
(aNumber = 0) ifTrue:[
- ^ ZeroDivide raiseRequestWith:thisContext.
+ ^ ZeroDivide raiseRequestWith:thisContext.
].
^ aNumber integerQuotientFromInteger:self
@@ -900,7 +900,7 @@
and the argument's value. The result is truncated towards zero
and negative, if the operands signs differ..
The following is always true:
- (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
+ (receiver quo: aNumber) * aNumber + (receiver rem: aNumber) = receiver
For positive results, this is the same as #//,
for negative results, the remainder is ignored.
I.e.: '9 // 4 = 2' and '-9 // 4 = -3'
@@ -911,39 +911,39 @@
return context._RETURN( self.quotient(aNumber));
#else
if (__isSmallInteger(aNumber)) {
- INT val = __intVal(aNumber);
- if (val != 0) {
- RETURN ( __mkSmallInteger(__intVal(self) / val) );
- }
+ INT val = __intVal(aNumber);
+ if (val != 0) {
+ RETURN ( __mkSmallInteger(__intVal(self) / val) );
+ }
} else {
- if (__isFractionLike(aNumber)) {
- OBJ t = __FractionInstPtr(aNumber)->f_numerator;
- if (__isSmallInteger(t)) {
- INT num = __intVal(t);
- t = __FractionInstPtr(aNumber)->f_denominator;
- if (__isSmallInteger(t)) {
- INT den = __intVal(t);
- INT myself = __intVal(self);
- INT prod;
+ if (__isFractionLike(aNumber)) {
+ OBJ t = __FractionInstPtr(aNumber)->f_numerator;
+ if (__isSmallInteger(t)) {
+ INT num = __intVal(t);
+ t = __FractionInstPtr(aNumber)->f_denominator;
+ if (__isSmallInteger(t)) {
+ INT den = __intVal(t);
+ INT myself = __intVal(self);
+ INT prod;
#if 0 && defined(__GNUC__) // supported from GCC 5
- if (__builtin_mul_overflow(myself, den, &prod)) {
- RETURN ( __mkSmallInteger(prod / num ));
- }
+ if (__builtin_mul_overflow(myself, den, &prod)) {
+ RETURN ( __mkSmallInteger(prod / num ));
+ }
#else
- prod = myself * den;
- // make sure, that no overflow occured
- if (prod / den == myself) {
- RETURN ( __mkSmallInteger(prod / num ));
- }
+ prod = myself * den;
+ // make sure, that no overflow occurred
+ if (prod / den == myself) {
+ RETURN ( __mkSmallInteger(prod / num ));
+ }
#endif
- }
- }
- }
+ }
+ }
+ }
}
#endif /* not __SCHTEAM__ */
%}.
(aNumber = 0) ifTrue:[
- ^ ZeroDivide raiseRequestWith:thisContext.
+ ^ ZeroDivide raiseRequestWith:thisContext.
].
^ self retry:#quo: coercing:aNumber