I read somewhere that in C short int range value are -32767 to +32767 http://www.ericgiguere.com/articles/ansi-c-summary.html And I was wondering why it does not follow the $-1 * 2^{N-1}\ to\ 2^{N-1}-1$ range encoding Stef On Dec 23, 2011, at 11:35 AM, Stéphane Ducasse wrote:
Hi
I'm doing a pass on the two complement chapter and small integer implementation and I wanted to check the SmallInteger>>primitiveAdd see below:
stackIntegerValue extracts from a smalltalk integer the 31 encoding number bit. I imagine that this is correct.
sqInt stackIntegerValue(sqInt offset) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt integerPointer; integerPointer = longAt(GIV(stackPointer) + (offset * BytesPerWord)); /* begin checkedIntegerValueOf: */ if ((integerPointer & 1)) { return (integerPointer >> 1); } else { /* begin primitiveFail */ if (GIV(primFailCode) == 0) { GIV(primFailCode) = 1; } return 0; } }
Now I have three questions: - is two complement used to manage small integers at VM level? I saw digitAdd on Integer and it deals with large integer.
- integerResult = (stackIntegerValue(1)) + (stackIntegerValue(0)); performs the real add. I imagine that it comes from plain C. Now does anybody has an idea where I could find the definition of such + procedure? In ANSI C
- from the books, performing 54 - 5 is equivalent to adding the two complement i.e. 54 + 5' (two complement) this work well for 54 - 5 correct results and we can follow it looking at binary operations:
(2r110110 - 2r101) bitString --> '0000000000000000000000000110001' (2r110110 bitString) --> '0000000000000000000000000110110' 2r101 bitString --> '0000000000000000000000000000101' 2r101 negated bitString --> '1111111111111111111111111111011'
Now doing 5 - 15 does not (or I miss something ilke always subtracting the smaller one and taking the two complement of the smallerâ¦) so does anybody has the answer on how to perform 5 - 15 ?
static void primitiveAdd(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt integerResult; char *sp;
/* begin pop2AndPushIntegerIfOK: */ integerResult = (stackIntegerValue(1)) + (stackIntegerValue(0)); if (GIV(primFailCode) == 0) { if ((integerResult ^ (integerResult << 1)) >= 0) { /* begin pop:thenPush: */ longAtput(sp = GIV(stackPointer) + ((2 - 1) * BytesPerWord), ((integerResult << 1) | 1)); GIV(stackPointer) = sp; } else { /* begin success: */ if (!(0)) { if (GIV(primFailCode) == 0) {
/* Don't overwrite an error code that has already been set. */
GIV(primFailCode) = 1; } } } } }
Stef