SmallInteger.st
changeset 927 8d8edf9df0ae
parent 829 fc386319f41c
child 1036 d79dc9e4c6f5
--- a/SmallInteger.st	Fri Feb 02 12:18:48 1996 +0100
+++ b/SmallInteger.st	Fri Feb 02 17:20:58 1996 +0100
@@ -373,8 +373,7 @@
 	_qMKFLOAT(newFloat, val, SENDER);
 	RETURN ( newFloat );
     }
-%}
-.
+%}.
     ^ aNumber differenceFromInteger:self
 !
 
@@ -419,8 +418,7 @@
 	    }
 	}
     }
-%}
-.
+%}.
     aNumber isInteger ifTrue:[
 	aNumber == 0 ifTrue:[
 	    ^ DivisionByZeroSignal raise.
@@ -428,11 +426,82 @@
 	^ Fraction numerator:self denominator:aNumber
     ].
     ^ aNumber quotientFromInteger:self
+
+    "
+     8 / 4
+     9 / 4
+     9 // 4
+     9 quo:4
+
+     -8 / 4
+     -9 / 4
+     -9 // 4
+     -9 quo:4
+    "
 !
 
 // aNumber
     "return the integer part of the quotient of the receivers value
-     and the arguments value"
+     and the arguments value.
+     Be careful with negative results: 9 // 4 = 2, 
+     while -9 // 4 = -3. 
+     See #quo: which returns -2 in the latter."
+
+%{  /* NOCONTEXT */
+    INT val, rslt;
+
+    if (__isSmallInteger(aNumber)) {
+	val = _intVal(aNumber);
+	if (val != 0) {
+	    rslt = _intVal(self) / val;
+	    if (rslt < 0) {
+		if (_intVal(self) % val)
+		    rslt--;
+	    }
+	    RETURN ( _MKSMALLINT(rslt) );
+	}
+    } else {
+	if (__isFraction(aNumber)) {
+	    OBJ t;
+	    INT num, den;
+
+	    t = _FractionInstPtr(aNumber)->f_numerator;
+	    if (__isSmallInteger(t)) {
+		num = _intVal(t);
+		t = _FractionInstPtr(aNumber)->f_denominator;
+		if (__isSmallInteger(t)) {
+		    den = _intVal(t);
+		    RETURN ( _MKSMALLINT(_intVal(self) * den / num ));
+		}
+	    }
+	}
+    }
+%}.
+    (aNumber = 0) ifTrue:[
+	^ DivisionByZeroSignal raise.
+    ].
+    ^ self retry:#// coercing:aNumber
+
+    "
+     9 // 4    => 2
+     -9 // 4   => -3
+     9 // -4   => -3
+     -9 // -4  => 2
+
+     9 quo:4   => 2
+     -9 quo:4  => -2
+     9 quo:-4  => -2
+     -9 quo:-4 => 2
+    "
+!
+
+quo:aNumber
+    "return the integer part of the quotient of the receivers value
+     and the arguments value. 
+     For positive results, this is the same as #//,
+     for negative results, the remainder is ignored.
+     I.e.: '9 // 4 = 2' and '-9 // 4 = -3'
+     in contrast: '9 quo: 4 = 2' and '-9 quo: 4 = -2'"
 
 %{  /* NOCONTEXT */
     INT val;
@@ -458,17 +527,24 @@
 	    }
 	}
     }
-%}
-.
+%}.
     (aNumber = 0) ifTrue:[
 	^ DivisionByZeroSignal raise.
     ].
-    ^ self retry:#// coercing:aNumber
+    ^ self retry:#quo: coercing:aNumber
+
+    "
+     9 // 4
+     -9 // 4
+     9 quo:4
+     -9 quo:4
+    "
 !
 
 \\ aNumber
     "return the integer rest of the receivers value
-     divided by the arguments value"
+     divided by the arguments value.
+     This is not always the same as the result as obtained from #rem:"
 
 %{  /* NOCONTEXT */
     INT mySelf, val;
@@ -484,12 +560,18 @@
 	    RETURN ( _MKSMALLINT(mySelf % val) );
 	}
     }
-%}
-.
+%}.
     (aNumber = 0) ifTrue:[
 	^ DivisionByZeroSignal raise.
     ].
     ^ self retry:#\\ coercing:aNumber
+
+    "
+     9 \\ 4
+     -9 \\ 4
+     9 rem:4
+     -9 rem:4
+    "
 !
 
 abs
@@ -588,9 +670,8 @@
     if (__isSmallInteger(anInteger)) {
 	RETURN ( ((OBJ) ((INT)self & (INT)anInteger)) );
     }
-%}
-.
-    ^ self retry:#bitAnd coercing:anInteger
+%}.
+    ^ self retry:#bitAnd: coercing:anInteger
 
     "(2r001010100 bitAnd:2r00001111) radixPrintStringRadix:2"
 !
@@ -630,9 +711,8 @@
     if (__isSmallInteger(anInteger)) {
 	RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
     }
-%}
-.
-    ^ self retry:#bitOr coercing:anInteger
+%}.
+    ^ self retry:#bitOr: coercing:anInteger
 
     "(2r000000100 bitOr:2r00000011) radixPrintStringRadix:2"
 !
@@ -725,7 +805,7 @@
     }
 %}
 .
-    ^ self retry:#bitTest coercing:aMask
+    ^ self retry:#bitTest: coercing:aMask
 !
 
 bitXor:anInteger
@@ -739,7 +819,7 @@
     }
 %}
 .
-    ^ self retry:#bitXor coercing:anInteger
+    ^ self retry:#bitXor: coercing:anInteger
 !
 
 highBit
@@ -1830,6 +1910,30 @@
     "123 printfPrintString:'%%04x -> %04x'"
 ! !
 
+!SmallInteger methodsFor:'private'!
+
+sign:aNumber
+    "private: for protocol completeness with LargeIntegers"
+
+    |absVal|
+
+    absVal := self abs.
+    aNumber < 0 ifTrue:[
+	^ absVal negated
+    ].
+    aNumber == 0 ifTrue:[^ 0].
+    ^ absVal
+
+    "
+     -4 sign:-1   
+     -4 sign:0    
+     -4 sign:1    
+     -4 sign:-1   
+     -4 sign:0    
+     -4 sign:1    
+    "
+! !
+
 !SmallInteger methodsFor:'testing'!
 
 between:min and:max
@@ -1950,5 +2054,5 @@
 !SmallInteger class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.43 1996-01-04 01:23:38 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.44 1996-02-02 16:20:51 cg Exp $'
 ! !