SmallInteger.st
changeset 701 a309e3ef7faf
parent 587 6b0b960020d5
child 809 5eef87c2907b
equal deleted inserted replaced
700:b4ae5ce39bfc 701:a309e3ef7faf
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 Integer subclass:#SmallInteger
    13 Integer subclass:#SmallInteger
    14        instanceVariableNames:''
    14 	 instanceVariableNames:''
    15        classVariableNames:''
    15 	 classVariableNames:''
    16        poolDictionaries:''
    16 	 poolDictionaries:''
    17        category:'Magnitude-Numbers'
    17 	 category:'Magnitude-Numbers'
    18 !
    18 !
    19 
    19 
    20 !SmallInteger class methodsFor:'documentation'!
    20 !SmallInteger class methodsFor:'documentation'!
    21 
    21 
    22 copyright
    22 copyright
    29  inclusion of the above copyright notice.   This software may not
    29  inclusion of the above copyright notice.   This software may not
    30  be provided or otherwise made available to, or used by, any
    30  be provided or otherwise made available to, or used by, any
    31  other person.  No title to or ownership of the software is
    31  other person.  No title to or ownership of the software is
    32  hereby transferred.
    32  hereby transferred.
    33 "
    33 "
    34 !
       
    35 
       
    36 version
       
    37     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.39 1995-11-20 20:18:17 cg Exp $'
       
    38 !
    34 !
    39 
    35 
    40 documentation
    36 documentation
    41 "
    37 "
    42     SmallIntegers are Integers in the range of at least +/- 2^30 
    38     SmallIntegers are Integers in the range of at least +/- 2^30 
    70      - SmallIntegers cannot be created with new"
    66      - SmallIntegers cannot be created with new"
    71 
    67 
    72     self error:'instances of SmallInteger cannot be created with new'
    68     self error:'instances of SmallInteger cannot be created with new'
    73 ! !
    69 ! !
    74 
    70 
       
    71 !SmallInteger class methodsFor:'binary storage'!
       
    72 
       
    73 binaryDefinitionFrom: stream manager: manager
       
    74     "read the binary representation as stored in storeBinaryOn:"
       
    75 
       
    76     | value |
       
    77 
       
    78     value := stream next bitAnd: 16r7F.
       
    79     value > 16r3F ifTrue: [
       
    80 	value := value - 16r80
       
    81     ].
       
    82     value := (value bitShift: 8) bitOr: stream next.
       
    83     value := (value bitShift: 8) bitOr: stream next.
       
    84     value := (value bitShift: 8) bitOr: stream next.
       
    85     ^ value
       
    86 ! !
       
    87 
       
    88 !SmallInteger class methodsFor:'bit mask constants'!
       
    89 
       
    90 bitMaskFor:index
       
    91     "return a bitmask for the index's bit (index starts at 1)"
       
    92 
       
    93     (index between:1 and:SmallInteger maxBits) ifFalse:[
       
    94 	^ self error:'index out of bounds'
       
    95     ].
       
    96     ^ 1 bitShift:(index - 1)
       
    97 ! !
       
    98 
    75 !SmallInteger class methodsFor:'constants'!
    99 !SmallInteger class methodsFor:'constants'!
    76 
   100 
    77 maxBits
   101 maxBits
    78     "return the number of bits in instances of me.
   102     "return the number of bits in instances of me.
    79      For very special uses only - not constant across implementations"
   103      For very special uses only - not constant across implementations"
    94 %}
   118 %}
    95 
   119 
    96     "SmallInteger maxBytes"
   120     "SmallInteger maxBytes"
    97 !
   121 !
    98 
   122 
       
   123 maxVal
       
   124     "return the largest Integer representable as SmallInteger.
       
   125      For very special uses only - not constant across implementations"
       
   126 
       
   127 %{  /* NOCONTEXT */
       
   128     RETURN ( _MKSMALLINT(_MAX_INT) );
       
   129 %}
       
   130 
       
   131     "SmallInteger maxVal"
       
   132 !
       
   133 
    99 minVal
   134 minVal
   100     "return the smallest Integer representable as SmallInteger.
   135     "return the smallest Integer representable as SmallInteger.
   101      For very special uses only - not constant across implementations"
   136      For very special uses only - not constant across implementations"
   102 
   137 
   103 %{  /* NOCONTEXT */
   138 %{  /* NOCONTEXT */
   104     RETURN ( _MKSMALLINT(_MIN_INT) );
   139     RETURN ( _MKSMALLINT(_MIN_INT) );
   105 %}
   140 %}
   106 
   141 
   107     "SmallInteger minVal"
   142     "SmallInteger minVal"
   108 !
       
   109 
       
   110 maxVal
       
   111     "return the largest Integer representable as SmallInteger.
       
   112      For very special uses only - not constant across implementations"
       
   113 
       
   114 %{  /* NOCONTEXT */
       
   115     RETURN ( _MKSMALLINT(_MAX_INT) );
       
   116 %}
       
   117 
       
   118     "SmallInteger maxVal"
       
   119 ! !
   143 ! !
   120 
   144 
   121 !SmallInteger class methodsFor:'queries'!
   145 !SmallInteger class methodsFor:'queries'!
   122 
       
   123 isBuiltInClass
       
   124     "this class is known by the run-time-system"
       
   125 
       
   126     ^ true
       
   127 !
       
   128 
   146 
   129 canBeSubclassed
   147 canBeSubclassed
   130     "return true, if its allowed to create subclasses of the receiver.
   148     "return true, if its allowed to create subclasses of the receiver.
   131      Return nil here - since it is NOT possible for SmallInteger"
   149      Return nil here - since it is NOT possible for SmallInteger"
   132 
   150 
   133     ^ false
   151     ^ false
       
   152 !
       
   153 
       
   154 isBuiltInClass
       
   155     "this class is known by the run-time-system"
       
   156 
       
   157     ^ true
   134 ! !
   158 ! !
   135 
   159 
   136 !SmallInteger methodsFor:'catching messages'!
       
   137 
       
   138 basicAt:index
       
   139     "catch indexed access - report an error
       
   140      defined here since basicAt: in Object ommits the SmallInteger check."
       
   141 
       
   142     self notIndexed
       
   143 !
       
   144 
       
   145 basicAt:index put:anObject
       
   146     "catch indexed access - report an error
       
   147      defined here since basicAt:put: in Object ommits the SmallInteger check."
       
   148 
       
   149     self notIndexed
       
   150 !
       
   151 
       
   152 size
       
   153     "return the number of indexed instvars - SmallIntegers have none."
       
   154 
       
   155     ^ 0
       
   156 !
       
   157 
       
   158 basicSize
       
   159     "return the number of indexed instvars - SmallIntegers have none.
       
   160      Defined here since basicSize in Object ommits the SmallInteger check."
       
   161 
       
   162     ^ 0
       
   163 ! !
       
   164 
       
   165 !SmallInteger methodsFor:'copying'!
       
   166 
       
   167 shallowCopy
       
   168     "return a shallow copy of myself
       
   169      - reimplemented here since smallintegers are unique"
       
   170 
       
   171     ^ self
       
   172 !
       
   173 
       
   174 simpleDeepCopy
       
   175     "return a deep copy of myself
       
   176      - reimplemented here since smallintegers are unique"
       
   177 
       
   178     ^ self
       
   179 !
       
   180 
       
   181 deepCopyUsing:aDictionary
       
   182     "return a deep copy of myself
       
   183      - reimplemented here since smallintegers are unique"
       
   184 
       
   185     ^ self
       
   186 !
       
   187 
       
   188 deepCopy
       
   189     "return a deep copy of myself
       
   190      - reimplemented here since smallintegers are unique"
       
   191 
       
   192     ^ self
       
   193 ! !
       
   194 
       
   195 !SmallInteger methodsFor:'comparing'!
       
   196 
       
   197 = aNumber
       
   198     "return true, if the arguments value is equal to mine"
       
   199 
       
   200 %{  /* NOCONTEXT */
       
   201 
       
   202     if (aNumber == self) {
       
   203 	RETURN ( true );
       
   204     }
       
   205     if (! __isNonNilObject(aNumber)) {
       
   206 	/* a smallint or nil */
       
   207 	RETURN ( false );
       
   208     }
       
   209 
       
   210     if (__isFloatLike(aNumber)) {
       
   211 	RETURN ( ((double)_intVal(self) == _floatVal(aNumber)) ? true : false );
       
   212     }
       
   213 %}
       
   214 .
       
   215     aNumber respondsToArithmetic ifFalse:[^ false].
       
   216     ^ self retry:#= coercing:aNumber
       
   217 !
       
   218 
       
   219 ~= aNumber
       
   220     "return true, if the arguments value is not equal to mine"
       
   221 
       
   222 %{  /* NOCONTEXT */
       
   223 
       
   224     if (aNumber == self) {
       
   225 	RETURN ( false );
       
   226     }
       
   227     if (! __isNonNilObject(aNumber)) {
       
   228 	/* a smallint or nil */
       
   229 	RETURN ( true );
       
   230     }
       
   231 
       
   232     if (__isFloatLike(aNumber)) {
       
   233 	RETURN ( ((double)_intVal(self) == _floatVal(aNumber)) ? false : true );
       
   234     }
       
   235 %}
       
   236 .
       
   237     aNumber respondsToArithmetic ifFalse:[^ true].
       
   238     ^ self retry:#~= coercing:aNumber
       
   239 !
       
   240 
       
   241 < aNumber
       
   242     "return true, if the argument is greater than the receiver"
       
   243 
       
   244 %{  /* NOCONTEXT */
       
   245 
       
   246     if (__isSmallInteger(aNumber)) {
       
   247 #ifdef POSITIVE_ADDRESSES
       
   248 	RETURN ( (_intVal(self) < _intVal(aNumber)) ? true : false );
       
   249 #else
       
   250 	/* tag bit does not change ordering */
       
   251 	RETURN ( ((INT)self < (INT)aNumber) ? true : false );
       
   252 #endif
       
   253     }
       
   254     if (__isFloatLike(aNumber)) {
       
   255 	RETURN ( ((double)_intVal(self) < _floatVal(aNumber)) ? true : false );
       
   256     }
       
   257 %}
       
   258 .
       
   259     ^ aNumber lessFromInteger:self
       
   260     "^ self retry:#< coercing:aNumber"
       
   261 !
       
   262 
       
   263 > aNumber
       
   264     "return true, if the argument is less than the receiver"
       
   265 
       
   266 %{  /* NOCONTEXT */
       
   267 
       
   268     if (__isSmallInteger(aNumber)) {
       
   269 #ifdef POSITIVE_ADDRESSES
       
   270 	RETURN ( (_intVal(self) > _intVal(aNumber)) ? true : false );
       
   271 #else
       
   272 	/* tag bit does not change ordering */
       
   273 	RETURN ( ((INT)self > (INT)aNumber) ? true : false );
       
   274 #endif
       
   275     }
       
   276     if (__isFloatLike(aNumber)) {
       
   277 	RETURN ( ((double)_intVal(self) > _floatVal(aNumber)) ? true : false );
       
   278     }
       
   279 %}
       
   280 .
       
   281     ^ self retry:#> coercing:aNumber
       
   282 !
       
   283 
       
   284 >= aNumber
       
   285     "return true, if the argument is less or equal"
       
   286 
       
   287 %{  /* NOCONTEXT */
       
   288 
       
   289     if (__isSmallInteger(aNumber)) {
       
   290 #ifdef POSITIVE_ADDRESSES
       
   291 	RETURN ( (_intVal(self) >= _intVal(aNumber)) ? true : false );
       
   292 #else
       
   293 	/* tag bit does not change ordering */
       
   294 	RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
       
   295 #endif
       
   296     }
       
   297     if (__isFloatLike(aNumber)) {
       
   298 	RETURN ( ((double)_intVal(self) >= _floatVal(aNumber)) ? true : false );
       
   299     }
       
   300 %}
       
   301 .
       
   302     ^ self retry:#>= coercing:aNumber
       
   303 !
       
   304 
       
   305 <= aNumber
       
   306     "return true, if the argument is greater or equal"
       
   307 
       
   308 %{  /* NOCONTEXT */
       
   309 
       
   310     if (__isSmallInteger(aNumber)) {
       
   311 #ifdef POSITIVE_ADDRESSES
       
   312 	RETURN ( (_intVal(self) <= _intVal(aNumber)) ? true : false );
       
   313 #else
       
   314 	/* tag bit does not change ordering */
       
   315 	RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
       
   316 #endif
       
   317     }
       
   318     if (__isFloatLike(aNumber)) {
       
   319 	RETURN ( ((double)_intVal(self) <= _floatVal(aNumber)) ? true : false );
       
   320     }
       
   321 %}
       
   322 .
       
   323     ^ self retry:#<= coercing:aNumber
       
   324 !
       
   325 
       
   326 hash
       
   327     "return an integer useful for hashing on value"
       
   328 
       
   329     self >= 0 ifTrue:[^ self].
       
   330     ^ self negated
       
   331 !
       
   332 
       
   333 identityHash
       
   334     "return an integer useful for hashing on identity"
       
   335 
       
   336     self >= 0 ifTrue:[^ self].
       
   337     ^ self negated
       
   338 !
       
   339 
       
   340 min:aNumber
       
   341     "return the receiver or the argument, whichever is smaller"
       
   342 
       
   343 %{  /* NOCONTEXT */
       
   344 
       
   345     if (__isSmallInteger(aNumber)) {
       
   346 #ifdef POSITIVE_ADDRESSES
       
   347 	if (_intVal(self) < _intVal(aNumber)) {
       
   348 #else
       
   349 	/* tag bit does not change ordering */
       
   350 	if ((INT)(self) < (INT)(aNumber)) {
       
   351 #endif
       
   352 	    RETURN ( self );
       
   353 	}
       
   354 	RETURN ( aNumber );
       
   355     }
       
   356     if (__isFloatLike(aNumber)) {
       
   357 	if ( (double)_intVal(self) < _floatVal(aNumber) ) {
       
   358 	    RETURN ( self );
       
   359 	}
       
   360 	RETURN ( aNumber );
       
   361     }
       
   362 %}
       
   363 .
       
   364     (self < aNumber) ifTrue:[^ self].
       
   365     ^ aNumber
       
   366 !
       
   367 
       
   368 max:aNumber
       
   369     "return the receiver or the argument, whichever is greater"
       
   370 
       
   371 %{  /* NOCONTEXT */
       
   372 
       
   373     if (__isSmallInteger(aNumber)) {
       
   374 #ifdef POSITIVE_ADDRESSES
       
   375 	if (_intVal(self) > _intVal(aNumber)) {
       
   376 #else
       
   377 	/* tag bit does not change ordering */
       
   378 	if ((INT)(self) > (INT)(aNumber)) {
       
   379 #endif
       
   380 	    RETURN ( self );
       
   381 	}
       
   382 	RETURN ( aNumber );
       
   383     }
       
   384     if (__isFloatLike(aNumber)) {
       
   385 	if ( (double)_intVal(self) > _floatVal(aNumber) ) {
       
   386 	    RETURN ( self );
       
   387 	}
       
   388 	RETURN ( aNumber );
       
   389     }
       
   390 %}
       
   391 .
       
   392     (self > aNumber) ifTrue:[^ self].
       
   393     ^ aNumber
       
   394 ! !
       
   395 
       
   396 !SmallInteger methodsFor:'testing'!
       
   397 
       
   398 negative
       
   399     "return true, if the receiver is less than zero
       
   400      reimplemented here for speed"
       
   401 
       
   402 %{  /* NOCONTEXT */
       
   403 
       
   404 #ifdef POSITIVE_ADDRESSES
       
   405     RETURN ( (_intVal(self) < 0) ? true : false );
       
   406 #else
       
   407     /* tag bit does not change sign */
       
   408     RETURN ( ((INT)(self) < 0) ? true : false );
       
   409 #endif
       
   410 %}
       
   411 !
       
   412 
       
   413 positive
       
   414     "return true, if the receiver is not negative
       
   415      reimplemented here for speed"
       
   416 
       
   417 %{  /* NOCONTEXT */
       
   418 
       
   419 #ifdef POSITIVE_ADDRESSES
       
   420     RETURN ( (_intVal(self) >= 0) ? true : false );
       
   421 #else
       
   422     /* tag bit does not change sign */
       
   423     RETURN ( ((INT)(self) >= 0) ? true : false );
       
   424 #endif
       
   425 %}
       
   426 !
       
   427 
       
   428 strictlyPositive
       
   429     "return true, if the receiver is greater than zero
       
   430      reimplemented here for speed"
       
   431 
       
   432 %{  /* NOCONTEXT */
       
   433 
       
   434 #ifdef POSITIVE_ADDRESSES
       
   435     RETURN ( (_intVal(self) > 0) ? true : false );
       
   436 #else
       
   437     /* tag bit does not change sign */
       
   438     RETURN ( ((INT)(self) > 0) ? true : false );
       
   439 #endif
       
   440 %}
       
   441 !
       
   442 
       
   443 sign
       
   444     "return the sign of the receiver
       
   445      reimplemented here for speed"
       
   446 
       
   447 %{  /* NOCONTEXT */
       
   448 
       
   449     INT val = _intVal(self);
       
   450 
       
   451     if (val < 0) {
       
   452 	RETURN ( _MKSMALLINT(-1) ); 
       
   453     }
       
   454     if (val > 0) {
       
   455 	RETURN ( _MKSMALLINT(1) );
       
   456     }
       
   457     RETURN ( _MKSMALLINT(0) );
       
   458 %}
       
   459 !
       
   460 
       
   461 between:min and:max
       
   462     "return true if the receiver is less than or equal to the argument max
       
   463      and greater than or equal to the argument min.
       
   464      - reimplemented here for speed"
       
   465 
       
   466 %{  /* NOCONTEXT */
       
   467 
       
   468     if (__bothSmallInteger(min, max)) {
       
   469 	REGISTER INT selfVal;
       
   470 
       
   471 	selfVal = _intVal(self);
       
   472 	if (selfVal < _intVal(min)) {
       
   473 	     RETURN ( false );
       
   474 	}
       
   475 	if (selfVal > _intVal(max)) {
       
   476 	     RETURN ( false );
       
   477 	}
       
   478 	RETURN ( true );
       
   479     }
       
   480 %}
       
   481 .
       
   482     (self < min) ifTrue:[^ false].
       
   483     (self > max) ifTrue:[^ false].
       
   484     ^ true
       
   485 !
       
   486 
       
   487 even
       
   488     "return true, if the receiver is even"
       
   489 
       
   490 %{  /* NOCONTEXT */
       
   491 
       
   492 #ifdef POSITIVE_ADDRESSES
       
   493     RETURN ( ((INT)self & 1) ? false : true );
       
   494 #else    
       
   495     RETURN ( ((INT)self & ((INT)_MKSMALLINT(1) & ~TAG_INT)) ? false : true );
       
   496 #endif
       
   497 %}
       
   498 !
       
   499 
       
   500 odd
       
   501     "return true, if the receiver is odd"
       
   502 
       
   503 %{  /* NOCONTEXT */
       
   504 
       
   505 #ifdef POSITIVE_ADDRESSES
       
   506     RETURN ( ((INT)self & 1) ? true : false );
       
   507 #else    
       
   508     RETURN ( ((INT)self & ((INT)_MKSMALLINT(1) & ~TAG_INT)) ? true : false );
       
   509 #endif
       
   510 %}
       
   511 ! !
       
   512 
       
   513 !SmallInteger methodsFor:'arithmetic'!
   160 !SmallInteger methodsFor:'arithmetic'!
   514 
       
   515 + aNumber
       
   516     "return the sum of the receivers value and the arguments value"
       
   517 
       
   518 %{  /* NOCONTEXT */
       
   519 
       
   520     if (__isSmallInteger(aNumber)) {
       
   521 #ifdef _ADD_IO_IO
       
   522 	RETURN ( _ADD_IO_IO(self, aNumber) );
       
   523 #else
       
   524 	REGISTER INT sum;
       
   525 	extern OBJ _MKLARGEINT();
       
   526 
       
   527 	sum =  _intVal(self) + _intVal(aNumber);
       
   528 	if ((sum >= _MIN_INT) && (sum <= _MAX_INT)) {
       
   529 	    RETURN ( _MKSMALLINT(sum) );
       
   530 	}
       
   531 	RETURN ( _MKLARGEINT(sum) );
       
   532 #endif
       
   533     }
       
   534     if (__isFloatLike(aNumber)) {
       
   535 	OBJ newFloat;
       
   536 	double val = (double)_intVal(self) + _floatVal(aNumber);
       
   537 
       
   538 	_qMKFLOAT(newFloat, val, SENDER);
       
   539 	RETURN ( newFloat );
       
   540     }
       
   541 %}
       
   542 .
       
   543     ^ aNumber sumFromInteger:self
       
   544 !
       
   545 
       
   546 - aNumber
       
   547     "return the difference of the receivers value and the arguments value"
       
   548 
       
   549 %{  /* NOCONTEXT */
       
   550 
       
   551     if (__isSmallInteger(aNumber)) {
       
   552 #ifdef _SUB_IO_IO
       
   553 	RETURN ( _SUB_IO_IO(self, aNumber) );
       
   554 #else
       
   555 	REGISTER INT diff;
       
   556 	extern OBJ _MKLARGEINT();
       
   557 
       
   558 	diff =  _intVal(self) - _intVal(aNumber);
       
   559 	if ((diff >= _MIN_INT) && (diff <= _MAX_INT)) {
       
   560 	    RETURN ( _MKSMALLINT(diff) );
       
   561 	}
       
   562 	RETURN ( _MKLARGEINT(diff) );
       
   563 #endif
       
   564     }
       
   565     if (__isFloatLike(aNumber)) {
       
   566 	OBJ newFloat;
       
   567 	double val = (double)_intVal(self) - _floatVal(aNumber);
       
   568 
       
   569 	_qMKFLOAT(newFloat, val, SENDER);
       
   570 	RETURN ( newFloat );
       
   571     }
       
   572 %}
       
   573 .
       
   574     ^ aNumber differenceFromInteger:self
       
   575 !
       
   576 
   161 
   577 * aNumber
   162 * aNumber
   578     "return the product of the receivers value and the arguments value"
   163     "return the product of the receivers value and the arguments value"
   579 
   164 
   580 %{  /* NOCONTEXT */
   165 %{  /* NOCONTEXT */
   732 %}
   317 %}
   733 .
   318 .
   734     ^ aNumber productFromInteger:self
   319     ^ aNumber productFromInteger:self
   735 !
   320 !
   736 
   321 
       
   322 + aNumber
       
   323     "return the sum of the receivers value and the arguments value"
       
   324 
       
   325 %{  /* NOCONTEXT */
       
   326 
       
   327     if (__isSmallInteger(aNumber)) {
       
   328 #ifdef _ADD_IO_IO
       
   329 	RETURN ( _ADD_IO_IO(self, aNumber) );
       
   330 #else
       
   331 	REGISTER INT sum;
       
   332 	extern OBJ _MKLARGEINT();
       
   333 
       
   334 	sum =  _intVal(self) + _intVal(aNumber);
       
   335 	if ((sum >= _MIN_INT) && (sum <= _MAX_INT)) {
       
   336 	    RETURN ( _MKSMALLINT(sum) );
       
   337 	}
       
   338 	RETURN ( _MKLARGEINT(sum) );
       
   339 #endif
       
   340     }
       
   341     if (__isFloatLike(aNumber)) {
       
   342 	OBJ newFloat;
       
   343 	double val = (double)_intVal(self) + _floatVal(aNumber);
       
   344 
       
   345 	_qMKFLOAT(newFloat, val, SENDER);
       
   346 	RETURN ( newFloat );
       
   347     }
       
   348 %}
       
   349 .
       
   350     ^ aNumber sumFromInteger:self
       
   351 !
       
   352 
       
   353 - aNumber
       
   354     "return the difference of the receivers value and the arguments value"
       
   355 
       
   356 %{  /* NOCONTEXT */
       
   357 
       
   358     if (__isSmallInteger(aNumber)) {
       
   359 #ifdef _SUB_IO_IO
       
   360 	RETURN ( _SUB_IO_IO(self, aNumber) );
       
   361 #else
       
   362 	REGISTER INT diff;
       
   363 	extern OBJ _MKLARGEINT();
       
   364 
       
   365 	diff =  _intVal(self) - _intVal(aNumber);
       
   366 	if ((diff >= _MIN_INT) && (diff <= _MAX_INT)) {
       
   367 	    RETURN ( _MKSMALLINT(diff) );
       
   368 	}
       
   369 	RETURN ( _MKLARGEINT(diff) );
       
   370 #endif
       
   371     }
       
   372     if (__isFloatLike(aNumber)) {
       
   373 	OBJ newFloat;
       
   374 	double val = (double)_intVal(self) - _floatVal(aNumber);
       
   375 
       
   376 	_qMKFLOAT(newFloat, val, SENDER);
       
   377 	RETURN ( newFloat );
       
   378     }
       
   379 %}
       
   380 .
       
   381     ^ aNumber differenceFromInteger:self
       
   382 !
       
   383 
   737 / aNumber
   384 / aNumber
   738     "return the quotient of the receivers value and the arguments value"
   385     "return the quotient of the receivers value and the arguments value"
   739 
   386 
   740 %{  /* NOCONTEXT */
   387 %{  /* NOCONTEXT */
   741 
   388 
   881 %}.
   528 %}.
   882     "only reached for minVal"
   529     "only reached for minVal"
   883     ^ (LargeInteger value:(SmallInteger maxVal)) + 1
   530     ^ (LargeInteger value:(SmallInteger maxVal)) + 1
   884 ! !
   531 ! !
   885 
   532 
   886 !SmallInteger methodsFor:'modulu arithmetic'!
   533 !SmallInteger methodsFor:'binary storage'!
   887 
   534 
   888 times:aNumber
   535 hasSpecialBinaryRepresentation
   889     "return the product of the receiver and the argument, as SmallInteger.
   536     "return true, if the receiver has a special binary representation"
   890      The argument must be another SmallInteger.
   537 
   891      If the result overflows the smallInteger range, the value modulu the 
   538     ^ true
   892      smallInteger range is returned (i.e. the low bits of the product).
   539 !
   893      This is of course not always correct, but some code does a modulu anyway
   540 
   894      and can therefore speed things up by not going through LargeIntegers."
   541 storeBinaryOn: stream manager: manager
   895 
   542     "append a binary representation onto stream.
   896 %{  /* NOCONTEXT */
   543      Redefined since SmallIntegers are stored as their value with the 32nd bit 
   897 
   544      set as a tag.
   898     if (__isSmallInteger(aNumber)) {
   545      To make the binary file a bit more compact, zeros and single byte ints
   899 	RETURN ( _MKSMALLINT((_intVal(self) * _intVal(aNumber)) & 0x7FFFFFFF) );
   546      are stored with a more compact representation (using special type-codes)."
   900     }
   547 
   901 %}
   548     self == 0 ifTrue:[
   902 .
   549 	stream nextPut: manager codeForZero.
   903     self primitiveFailed
   550 	^ self
   904 !
   551     ].
   905 
   552     (self between:0 and:255) ifTrue:[
   906 plus:aNumber
   553 	stream nextPut: manager codeForByteInteger.
   907     "return the sum of the receiver and the argument, as SmallInteger.
   554 	stream nextPut: self.
   908      The argument must be another SmallInteger.
   555 	^ self
   909      If the result overflows the smallInteger range, the value modulu the 
   556     ].
   910      smallInteger range is returned (i.e. the low bits of the sum).
   557     stream nextPut: (((self bitShift: -24) bitAnd: 16rFF) bitOr: 16r80).
   911      This is of course not always correct, but some code does a modulu anyway
   558     stream nextPut: ((self bitShift: -16) bitAnd: 16rFF).
   912      and can therefore speed things up by not going through LargeIntegers."
   559     stream nextPut: ((self bitShift: -8) bitAnd: 16rFF).
   913 
   560     stream nextPut: (self bitAnd: 16rFF)
   914 %{  /* NOCONTEXT */
       
   915 
       
   916     if (__isSmallInteger(aNumber)) {
       
   917 	RETURN ( _MKSMALLINT((_intVal(self) + _intVal(aNumber)) & 0x7FFFFFFF) );
       
   918     }
       
   919 %}
       
   920 .
       
   921     self primitiveFailed
       
   922 ! 
       
   923 
       
   924 subtract:aNumber
       
   925     "return the difference of the receiver and the argument, as SmallInteger.
       
   926      The argument must be another SmallInteger.
       
   927      If the result overflows the smallInteger range, the value modulu the 
       
   928      smallInteger range is returned (i.e. the low bits of the sum).
       
   929      This is of course not always correct, but some code does a modulu anyway
       
   930      and can therefore speed things up by not going through LargeIntegers."
       
   931 
       
   932 %{  /* NOCONTEXT */
       
   933 
       
   934     if (__isSmallInteger(aNumber)) {
       
   935 	RETURN ( _MKSMALLINT((_intVal(self) - _intVal(aNumber)) & 0x7FFFFFFF) );
       
   936     }
       
   937 %}
       
   938 .
       
   939     self primitiveFailed
       
   940 ! !
   561 ! !
   941 
   562 
   942 !SmallInteger class methodsFor:'bit mask constants'!
       
   943 
       
   944 bitMaskFor:index
       
   945     "return a bitmask for the index's bit (index starts at 1)"
       
   946 
       
   947     (index between:1 and:SmallInteger maxBits) ifFalse:[
       
   948 	^ self error:'index out of bounds'
       
   949     ].
       
   950     ^ 1 bitShift:(index - 1)
       
   951 ! !
       
   952 
       
   953 !SmallInteger methodsFor:'bit operators'!
   563 !SmallInteger methodsFor:'bit operators'!
       
   564 
       
   565 allMask:anInteger
       
   566     "return true if all 1-bits in anInteger are also 1 in the receiver"
       
   567 
       
   568     ^ (self bitAnd:anInteger) == anInteger
       
   569 
       
   570     "2r00001111 allMask:2r00000001"
       
   571     "2r00001111 allMask:2r00011110"
       
   572     "2r00001111 allMask:2r00000000"
       
   573 !
       
   574 
       
   575 anyMask:anInteger
       
   576     "return true if any 1-bits in anInteger is also 1 in the receiver.
       
   577      (somewhat incorrect, if the mask is zero)"
       
   578 
       
   579     ^ (self bitAnd:anInteger) ~~ 0
       
   580 
       
   581     "2r00001111 anyMask:2r00000001"
       
   582     "2r00001111 anyMask:2r11110000"
       
   583 !
       
   584 
       
   585 bitAnd:anInteger
       
   586     "return the bitwise-and of the receiver and the argument, anInteger"
       
   587 
       
   588 %{  /* NOCONTEXT */
       
   589 
       
   590     /* anding the tags doesn't change it */
       
   591     if (__isSmallInteger(anInteger)) {
       
   592 	RETURN ( ((OBJ) ((INT)self & (INT)anInteger)) );
       
   593     }
       
   594 %}
       
   595 .
       
   596     ^ self retry:#bitAnd coercing:anInteger
       
   597 
       
   598     "(2r001010100 bitAnd:2r00001111) radixPrintStringRadix:2"
       
   599 !
   954 
   600 
   955 bitAt:index
   601 bitAt:index
   956     "return the value of the index's bit (index starts at 1).
   602     "return the value of the index's bit (index starts at 1).
   957      Notice: the result of bitAt: on negative receivers is not 
   603      Notice: the result of bitAt: on negative receivers is not 
   958 	     defined in the language standard (since the implementation
   604 	     defined in the language standard (since the implementation
   966     mask := 1 bitShift:(index - 1).
   612     mask := 1 bitShift:(index - 1).
   967     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
   613     ((self bitAnd:mask) == 0) ifTrue:[^ 0].
   968     ^ 1
   614     ^ 1
   969 !
   615 !
   970 
   616 
   971 allMask:anInteger
   617 bitInvert
   972     "return true if all 1-bits in anInteger are also 1 in the receiver"
   618     "return the value of the receiver with all bits inverted"
   973 
   619 
   974     ^ (self bitAnd:anInteger) == anInteger
   620 %{  /* NOCONTEXT */
   975 
   621 
   976     "2r00001111 allMask:2r00000001"
   622     /* invert anything except tag bits */
   977     "2r00001111 allMask:2r00011110"
   623     RETURN ( ((OBJ) ((INT)self ^ ~TAG_MASK)) );
   978     "2r00001111 allMask:2r00000000"
   624 %}
   979 !
   625 !
   980 
   626 
   981 anyMask:anInteger
   627 bitOr:anInteger
   982     "return true if any 1-bits in anInteger is also 1 in the receiver.
   628     "return the bitwise-or of the receiver and the argument, anInteger"
   983      (somewhat incorrect, if the mask is zero)"
   629 
   984 
   630 %{  /* NOCONTEXT */
   985     ^ (self bitAnd:anInteger) ~~ 0
   631 
   986 
   632     /* oring the tags doesn't change it */
   987     "2r00001111 anyMask:2r00000001"
   633     if (__isSmallInteger(anInteger)) {
   988     "2r00001111 anyMask:2r11110000"
   634 	RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
   989 !
   635     }
   990 
   636 %}
   991 noMask:anInteger
   637 .
   992     "return true if no 1-bit in anInteger is 1 in the receiver"
   638     ^ self retry:#bitOr coercing:anInteger
   993 
   639 
   994     ^ (self bitAnd:anInteger) == 0
   640     "(2r000000100 bitOr:2r00000011) radixPrintStringRadix:2"
   995 
       
   996     "2r00001111 noMask:2r00000001"
       
   997     "2r00001111 noMask:2r11110000"
       
   998 !
       
   999 
       
  1000 highBit
       
  1001     "return the bitIndex of the highest bit set. The returned bitIndex
       
  1002      starts at 1 for the least significant bit. Returns -1 if no bit is set."
       
  1003 
       
  1004 %{  /* NOCONTEXT */
       
  1005 
       
  1006     INT mask, index, bits;
       
  1007 
       
  1008     bits = _intVal(self);
       
  1009     if (bits == 0) {
       
  1010 	RETURN ( _MKSMALLINT(-1) );
       
  1011     }
       
  1012 #ifdef alpha
       
  1013     mask = 0x2000000000000000;
       
  1014     index = 62;
       
  1015 #else
       
  1016     mask = 0x20000000;
       
  1017     index = 30;
       
  1018 #endif
       
  1019     while (index) {
       
  1020 	if (bits & mask) break;
       
  1021 	mask = mask >> 1;
       
  1022 	index--;
       
  1023     }
       
  1024     RETURN ( _MKSMALLINT(index) );
       
  1025 %}
       
  1026     "2r000100 highBit"
       
  1027     "2r010100 highBit"
       
  1028     "2r000001 highBit"
       
  1029     "0 highBit"
       
  1030     "SmallInteger maxVal highBit"
       
  1031 !
       
  1032 
       
  1033 lowBit
       
  1034     "return the bitIndex of the lowest bit set. The returned bitIndex
       
  1035      starts at 1 for the least significant bit. Returns -1 if no bit is set."
       
  1036 
       
  1037 %{  /* NOCONTEXT */
       
  1038 
       
  1039     INT mask, index, bits;
       
  1040 
       
  1041     bits = _intVal(self);
       
  1042     if (bits == 0) {
       
  1043 	RETURN ( _MKSMALLINT(-1) );
       
  1044     }
       
  1045     mask = 1;
       
  1046     index = 1;
       
  1047 #ifdef alpha
       
  1048     while (index != 63) {
       
  1049 #else
       
  1050     while (index != 31) {
       
  1051 #endif
       
  1052 	if (bits & mask) {
       
  1053 	    RETURN ( _MKSMALLINT(index) );
       
  1054 	}
       
  1055 	mask = mask << 1;
       
  1056 	index++;
       
  1057     }
       
  1058     RETURN ( _MKSMALLINT(-1) );
       
  1059 %}
       
  1060     "2r000100 lowBit"
       
  1061     "2r010010 lowBit"
       
  1062     "2r100001 lowBit"
       
  1063     "0 lowBit"
       
  1064 !
   641 !
  1065 
   642 
  1066 bitShift:shiftCount
   643 bitShift:shiftCount
  1067     "return the value of the receiver shifted by shiftCount bits;
   644     "return the value of the receiver shifted by shiftCount bits;
  1068      leftShift if shiftCount > 0; rightShift otherwise.
   645      leftShift if shiftCount > 0; rightShift otherwise.
  1139 	^ (LargeInteger value:self) bitShift:shiftCount
   716 	^ (LargeInteger value:self) bitShift:shiftCount
  1140     ].
   717     ].
  1141     ^ self bitShift:(shiftCount coerce:1)
   718     ^ self bitShift:(shiftCount coerce:1)
  1142 !
   719 !
  1143 
   720 
  1144 bitOr:anInteger
   721 bitTest:aMask
  1145     "return the bitwise-or of the receiver and the argument, anInteger"
   722     "return true, if any bit from aMask is set in the receiver"
  1146 
   723 
  1147 %{  /* NOCONTEXT */
   724 %{  /* NOCONTEXT */
  1148 
   725 
  1149     /* oring the tags doesn't change it */
   726     /* and all bits except tag */
  1150     if (__isSmallInteger(anInteger)) {
   727     if (__isSmallInteger(aMask)) {
  1151 	RETURN ( ((OBJ) ((INT)self | (INT)anInteger)) );
   728 	RETURN ( ((INT)self & ((INT)aMask & ~TAG_MASK)) ? true : false );
  1152     }
   729     }
  1153 %}
   730 %}
  1154 .
   731 .
  1155     ^ self retry:#bitOr coercing:anInteger
   732     ^ self retry:#bitTest coercing:aMask
  1156 
       
  1157     "(2r000000100 bitOr:2r00000011) radixPrintStringRadix:2"
       
  1158 !
       
  1159 
       
  1160 bitAnd:anInteger
       
  1161     "return the bitwise-and of the receiver and the argument, anInteger"
       
  1162 
       
  1163 %{  /* NOCONTEXT */
       
  1164 
       
  1165     /* anding the tags doesn't change it */
       
  1166     if (__isSmallInteger(anInteger)) {
       
  1167 	RETURN ( ((OBJ) ((INT)self & (INT)anInteger)) );
       
  1168     }
       
  1169 %}
       
  1170 .
       
  1171     ^ self retry:#bitAnd coercing:anInteger
       
  1172 
       
  1173     "(2r001010100 bitAnd:2r00001111) radixPrintStringRadix:2"
       
  1174 !
   733 !
  1175 
   734 
  1176 bitXor:anInteger
   735 bitXor:anInteger
  1177     "return the bitwise-exclusive-or of the receiver and the argument, anInteger"
   736     "return the bitwise-exclusive-or of the receiver and the argument, anInteger"
  1178 
   737 
  1185 %}
   744 %}
  1186 .
   745 .
  1187     ^ self retry:#bitXor coercing:anInteger
   746     ^ self retry:#bitXor coercing:anInteger
  1188 !
   747 !
  1189 
   748 
  1190 bitInvert
   749 highBit
  1191     "return the value of the receiver with all bits inverted"
   750     "return the bitIndex of the highest bit set. The returned bitIndex
  1192 
   751      starts at 1 for the least significant bit. Returns -1 if no bit is set."
  1193 %{  /* NOCONTEXT */
   752 
  1194 
   753 %{  /* NOCONTEXT */
  1195     /* invert anything except tag bits */
   754 
  1196     RETURN ( ((OBJ) ((INT)self ^ ~TAG_MASK)) );
   755     INT mask, index, bits;
  1197 %}
   756 
  1198 !
   757     bits = _intVal(self);
  1199 
   758     if (bits == 0) {
  1200 bitTest:aMask
   759 	RETURN ( _MKSMALLINT(-1) );
  1201     "return true, if any bit from aMask is set in the receiver"
   760     }
  1202 
   761 #ifdef alpha
  1203 %{  /* NOCONTEXT */
   762     mask = 0x2000000000000000;
  1204 
   763     index = 62;
  1205     /* and all bits except tag */
   764 #else
  1206     if (__isSmallInteger(aMask)) {
   765     mask = 0x20000000;
  1207 	RETURN ( ((INT)self & ((INT)aMask & ~TAG_MASK)) ? true : false );
   766     index = 30;
  1208     }
   767 #endif
  1209 %}
   768     while (index) {
  1210 .
   769 	if (bits & mask) break;
  1211     ^ self retry:#bitTest coercing:aMask
   770 	mask = mask >> 1;
       
   771 	index--;
       
   772     }
       
   773     RETURN ( _MKSMALLINT(index) );
       
   774 %}
       
   775     "2r000100 highBit"
       
   776     "2r010100 highBit"
       
   777     "2r000001 highBit"
       
   778     "0 highBit"
       
   779     "SmallInteger maxVal highBit"
       
   780 !
       
   781 
       
   782 lowBit
       
   783     "return the bitIndex of the lowest bit set. The returned bitIndex
       
   784      starts at 1 for the least significant bit. Returns -1 if no bit is set."
       
   785 
       
   786 %{  /* NOCONTEXT */
       
   787 
       
   788     INT mask, index, bits;
       
   789 
       
   790     bits = _intVal(self);
       
   791     if (bits == 0) {
       
   792 	RETURN ( _MKSMALLINT(-1) );
       
   793     }
       
   794     mask = 1;
       
   795     index = 1;
       
   796 #ifdef alpha
       
   797     while (index != 63) {
       
   798 #else
       
   799     while (index != 31) {
       
   800 #endif
       
   801 	if (bits & mask) {
       
   802 	    RETURN ( _MKSMALLINT(index) );
       
   803 	}
       
   804 	mask = mask << 1;
       
   805 	index++;
       
   806     }
       
   807     RETURN ( _MKSMALLINT(-1) );
       
   808 %}
       
   809     "2r000100 lowBit"
       
   810     "2r010010 lowBit"
       
   811     "2r100001 lowBit"
       
   812     "0 lowBit"
       
   813 !
       
   814 
       
   815 noMask:anInteger
       
   816     "return true if no 1-bit in anInteger is 1 in the receiver"
       
   817 
       
   818     ^ (self bitAnd:anInteger) == 0
       
   819 
       
   820     "2r00001111 noMask:2r00000001"
       
   821     "2r00001111 noMask:2r11110000"
  1212 ! !
   822 ! !
  1213 
   823 
  1214 !SmallInteger methodsFor:'byte access'!
   824 !SmallInteger methodsFor:'byte access'!
  1215 
       
  1216 digitLength
       
  1217     "return the number bytes used by this Integer"
       
  1218 
       
  1219     ^ self abs highBit - 1 // 8 + 1
       
  1220 !
       
  1221 
   825 
  1222 digitAt:index
   826 digitAt:index
  1223     "return 8 bits of value, starting at byte index"
   827     "return 8 bits of value, starting at byte index"
  1224 
   828 
  1225 %{  /* NOCONTEXT */
   829 %{  /* NOCONTEXT */
  1280      (16r12345678 digitAt:3) printStringRadix:16
   884      (16r12345678 digitAt:3) printStringRadix:16
  1281      (16r12345678 digitAt:15) printStringRadix:16
   885      (16r12345678 digitAt:15) printStringRadix:16
  1282      (16r12345678 digitAt:0) printStringRadix:16
   886      (16r12345678 digitAt:0) printStringRadix:16
  1283      (16r12345678 digitAt:-10) printStringRadix:16
   887      (16r12345678 digitAt:-10) printStringRadix:16
  1284     "
   888     "
       
   889 !
       
   890 
       
   891 digitLength
       
   892     "return the number bytes used by this Integer"
       
   893 
       
   894     ^ self abs highBit - 1 // 8 + 1
  1285 ! !
   895 ! !
  1286 
   896 
  1287 !SmallInteger methodsFor:'misc math'!
   897 !SmallInteger methodsFor:'catching messages'!
  1288 
   898 
  1289 gcd:anInteger
   899 basicAt:index
  1290     "return the greatest common divisor (Euclid's algorithm).
   900     "catch indexed access - report an error
  1291      This has been redefined here for more speed since due to the
   901      defined here since basicAt: in Object ommits the SmallInteger check."
  1292      use of gcd in Fraction code, it has become time-critical for
   902 
  1293      some code. (thanx to MessageTally)"
   903     self notIndexed
  1294 
   904 !
  1295 %{  /* NOCONTEXT */
   905 
  1296 
   906 basicAt:index put:anObject
  1297     if (__isSmallInteger(anInteger)) {
   907     "catch indexed access - report an error
  1298 	INT orgArg, ttt, selfInt, temp;
   908      defined here since basicAt:put: in Object ommits the SmallInteger check."
  1299 
   909 
  1300 	ttt = orgArg = _intVal(anInteger);
   910     self notIndexed
  1301 	if (ttt) {
   911 !
  1302 	    selfInt = _intVal(self);
   912 
  1303 	    while (ttt != 0) {
   913 basicSize
  1304 		temp = selfInt % ttt;
   914     "return the number of indexed instvars - SmallIntegers have none.
  1305 		selfInt = ttt;
   915      Defined here since basicSize in Object ommits the SmallInteger check."
  1306 		ttt = temp;
   916 
  1307 	    }
   917     ^ 0
  1308 	    /*
   918 !
  1309 	     * since its not defined in what the sign of
   919 
  1310 	     * a modulu result is when the arg is negative,
   920 size
  1311 	     * change it explicitely here ...
   921     "return the number of indexed instvars - SmallIntegers have none."
  1312 	     */
   922 
  1313 	    if (orgArg < 0) {
   923     ^ 0
  1314 		/* result should be negative */
       
  1315 		if (selfInt > 0) selfInt = -selfInt;
       
  1316 	    } else {
       
  1317 		/* result should be positive */
       
  1318 		if (selfInt < 0) selfInt = -selfInt;
       
  1319 	    }
       
  1320 	    RETURN ( _MKSMALLINT(selfInt) );
       
  1321 	}
       
  1322     }
       
  1323 %}
       
  1324 .
       
  1325     ^ super gcd:anInteger
       
  1326 !
       
  1327 
       
  1328 intlog10
       
  1329     "return the truncation of log10 of the receiver -
       
  1330      stupid implementation; used to find out the number of digits needed
       
  1331      to print a number/and for conversion to a LargeInteger.
       
  1332      Implemented that way, to allow for tiny systems without a Float class
       
  1333      (i.e. without log)."
       
  1334 
       
  1335     self <= 0 ifTrue:[
       
  1336 	self error:'logarithm of negative integer'
       
  1337     ].
       
  1338     self < 10 ifTrue:[^ 1].
       
  1339     self < 100 ifTrue:[^ 2].
       
  1340     self < 1000 ifTrue:[^ 3].
       
  1341     self < 10000 ifTrue:[^ 4].
       
  1342     self < 100000 ifTrue:[^ 5].
       
  1343     self < 1000000 ifTrue:[^ 6].
       
  1344     self < 10000000 ifTrue:[^ 7].
       
  1345     self < 100000000 ifTrue:[^ 8].
       
  1346     self < 1000000000 ifTrue:[^ 9].
       
  1347     ^ 10
       
  1348 ! !
   924 ! !
  1349 
   925 
  1350 !SmallInteger methodsFor:'coercing and converting'!
   926 !SmallInteger methodsFor:'coercing and converting'!
       
   927 
       
   928 asCharacter
       
   929     "Return a character with the receiver as ascii value"
       
   930 
       
   931     ^ Character value:self
       
   932 !
       
   933 
       
   934 asFloat
       
   935     "return a Float with same value as receiver"
       
   936 
       
   937 %{  /* NOCONTEXT */
       
   938 
       
   939     OBJ newFloat;
       
   940     double dVal = (double)_intVal(self);
       
   941 
       
   942     _qMKFLOAT(newFloat, dVal, SENDER);
       
   943     RETURN ( newFloat );
       
   944 %}
       
   945 !
       
   946 
       
   947 asLargeInteger
       
   948     "return a LargeInteger with same value as receiver"
       
   949 
       
   950     ^ LargeInteger value:self
       
   951 !
  1351 
   952 
  1352 coerce:aNumber
   953 coerce:aNumber
  1353     "return aNumber converted into receivers type"
   954     "return aNumber converted into receivers type"
  1354 
   955 
  1355     ^ aNumber asInteger
   956     ^ aNumber asInteger
  1357 
   958 
  1358 generality
   959 generality
  1359     "return the generality value - see ArithmeticValue>>retry:coercing:"
   960     "return the generality value - see ArithmeticValue>>retry:coercing:"
  1360 
   961 
  1361     ^ 20
   962     ^ 20
  1362 !
   963 ! !
  1363 
   964 
  1364 asFloat
   965 !SmallInteger methodsFor:'comparing'!
  1365     "return a Float with same value as receiver"
   966 
  1366 
   967 < aNumber
  1367 %{  /* NOCONTEXT */
   968     "return true, if the argument is greater than the receiver"
  1368 
   969 
  1369     OBJ newFloat;
   970 %{  /* NOCONTEXT */
  1370     double dVal = (double)_intVal(self);
   971 
  1371 
   972     if (__isSmallInteger(aNumber)) {
  1372     _qMKFLOAT(newFloat, dVal, SENDER);
   973 #ifdef POSITIVE_ADDRESSES
  1373     RETURN ( newFloat );
   974 	RETURN ( (_intVal(self) < _intVal(aNumber)) ? true : false );
  1374 %}
   975 #else
  1375 !
   976 	/* tag bit does not change ordering */
  1376 
   977 	RETURN ( ((INT)self < (INT)aNumber) ? true : false );
  1377 asLargeInteger
   978 #endif
  1378     "return a LargeInteger with same value as receiver"
   979     }
  1379 
   980     if (__isFloatLike(aNumber)) {
  1380     ^ LargeInteger value:self
   981 	RETURN ( ((double)_intVal(self) < _floatVal(aNumber)) ? true : false );
  1381 !
   982     }
  1382 
   983 %}
  1383 asCharacter
   984 .
  1384     "Return a character with the receiver as ascii value"
   985     ^ aNumber lessFromInteger:self
  1385 
   986     "^ self retry:#< coercing:aNumber"
  1386     ^ Character value:self
   987 !
       
   988 
       
   989 <= aNumber
       
   990     "return true, if the argument is greater or equal"
       
   991 
       
   992 %{  /* NOCONTEXT */
       
   993 
       
   994     if (__isSmallInteger(aNumber)) {
       
   995 #ifdef POSITIVE_ADDRESSES
       
   996 	RETURN ( (_intVal(self) <= _intVal(aNumber)) ? true : false );
       
   997 #else
       
   998 	/* tag bit does not change ordering */
       
   999 	RETURN ( ((INT)self <= (INT)aNumber) ? true : false );
       
  1000 #endif
       
  1001     }
       
  1002     if (__isFloatLike(aNumber)) {
       
  1003 	RETURN ( ((double)_intVal(self) <= _floatVal(aNumber)) ? true : false );
       
  1004     }
       
  1005 %}
       
  1006 .
       
  1007     ^ self retry:#<= coercing:aNumber
       
  1008 !
       
  1009 
       
  1010 = aNumber
       
  1011     "return true, if the arguments value is equal to mine"
       
  1012 
       
  1013 %{  /* NOCONTEXT */
       
  1014 
       
  1015     if (aNumber == self) {
       
  1016 	RETURN ( true );
       
  1017     }
       
  1018     if (! __isNonNilObject(aNumber)) {
       
  1019 	/* a smallint or nil */
       
  1020 	RETURN ( false );
       
  1021     }
       
  1022 
       
  1023     if (__isFloatLike(aNumber)) {
       
  1024 	RETURN ( ((double)_intVal(self) == _floatVal(aNumber)) ? true : false );
       
  1025     }
       
  1026 %}
       
  1027 .
       
  1028     aNumber respondsToArithmetic ifFalse:[^ false].
       
  1029     ^ self retry:#= coercing:aNumber
       
  1030 !
       
  1031 
       
  1032 > aNumber
       
  1033     "return true, if the argument is less than the receiver"
       
  1034 
       
  1035 %{  /* NOCONTEXT */
       
  1036 
       
  1037     if (__isSmallInteger(aNumber)) {
       
  1038 #ifdef POSITIVE_ADDRESSES
       
  1039 	RETURN ( (_intVal(self) > _intVal(aNumber)) ? true : false );
       
  1040 #else
       
  1041 	/* tag bit does not change ordering */
       
  1042 	RETURN ( ((INT)self > (INT)aNumber) ? true : false );
       
  1043 #endif
       
  1044     }
       
  1045     if (__isFloatLike(aNumber)) {
       
  1046 	RETURN ( ((double)_intVal(self) > _floatVal(aNumber)) ? true : false );
       
  1047     }
       
  1048 %}
       
  1049 .
       
  1050     ^ self retry:#> coercing:aNumber
       
  1051 !
       
  1052 
       
  1053 >= aNumber
       
  1054     "return true, if the argument is less or equal"
       
  1055 
       
  1056 %{  /* NOCONTEXT */
       
  1057 
       
  1058     if (__isSmallInteger(aNumber)) {
       
  1059 #ifdef POSITIVE_ADDRESSES
       
  1060 	RETURN ( (_intVal(self) >= _intVal(aNumber)) ? true : false );
       
  1061 #else
       
  1062 	/* tag bit does not change ordering */
       
  1063 	RETURN ( ((INT)self >= (INT)aNumber) ? true : false );
       
  1064 #endif
       
  1065     }
       
  1066     if (__isFloatLike(aNumber)) {
       
  1067 	RETURN ( ((double)_intVal(self) >= _floatVal(aNumber)) ? true : false );
       
  1068     }
       
  1069 %}
       
  1070 .
       
  1071     ^ self retry:#>= coercing:aNumber
       
  1072 !
       
  1073 
       
  1074 hash
       
  1075     "return an integer useful for hashing on value"
       
  1076 
       
  1077     self >= 0 ifTrue:[^ self].
       
  1078     ^ self negated
       
  1079 !
       
  1080 
       
  1081 identityHash
       
  1082     "return an integer useful for hashing on identity"
       
  1083 
       
  1084     self >= 0 ifTrue:[^ self].
       
  1085     ^ self negated
       
  1086 !
       
  1087 
       
  1088 max:aNumber
       
  1089     "return the receiver or the argument, whichever is greater"
       
  1090 
       
  1091 %{  /* NOCONTEXT */
       
  1092 
       
  1093     if (__isSmallInteger(aNumber)) {
       
  1094 #ifdef POSITIVE_ADDRESSES
       
  1095 	if (_intVal(self) > _intVal(aNumber)) {
       
  1096 #else
       
  1097 	/* tag bit does not change ordering */
       
  1098 	if ((INT)(self) > (INT)(aNumber)) {
       
  1099 #endif
       
  1100 	    RETURN ( self );
       
  1101 	}
       
  1102 	RETURN ( aNumber );
       
  1103     }
       
  1104     if (__isFloatLike(aNumber)) {
       
  1105 	if ( (double)_intVal(self) > _floatVal(aNumber) ) {
       
  1106 	    RETURN ( self );
       
  1107 	}
       
  1108 	RETURN ( aNumber );
       
  1109     }
       
  1110 %}
       
  1111 .
       
  1112     (self > aNumber) ifTrue:[^ self].
       
  1113     ^ aNumber
       
  1114 !
       
  1115 
       
  1116 min:aNumber
       
  1117     "return the receiver or the argument, whichever is smaller"
       
  1118 
       
  1119 %{  /* NOCONTEXT */
       
  1120 
       
  1121     if (__isSmallInteger(aNumber)) {
       
  1122 #ifdef POSITIVE_ADDRESSES
       
  1123 	if (_intVal(self) < _intVal(aNumber)) {
       
  1124 #else
       
  1125 	/* tag bit does not change ordering */
       
  1126 	if ((INT)(self) < (INT)(aNumber)) {
       
  1127 #endif
       
  1128 	    RETURN ( self );
       
  1129 	}
       
  1130 	RETURN ( aNumber );
       
  1131     }
       
  1132     if (__isFloatLike(aNumber)) {
       
  1133 	if ( (double)_intVal(self) < _floatVal(aNumber) ) {
       
  1134 	    RETURN ( self );
       
  1135 	}
       
  1136 	RETURN ( aNumber );
       
  1137     }
       
  1138 %}
       
  1139 .
       
  1140     (self < aNumber) ifTrue:[^ self].
       
  1141     ^ aNumber
       
  1142 !
       
  1143 
       
  1144 ~= aNumber
       
  1145     "return true, if the arguments value is not equal to mine"
       
  1146 
       
  1147 %{  /* NOCONTEXT */
       
  1148 
       
  1149     if (aNumber == self) {
       
  1150 	RETURN ( false );
       
  1151     }
       
  1152     if (! __isNonNilObject(aNumber)) {
       
  1153 	/* a smallint or nil */
       
  1154 	RETURN ( true );
       
  1155     }
       
  1156 
       
  1157     if (__isFloatLike(aNumber)) {
       
  1158 	RETURN ( ((double)_intVal(self) == _floatVal(aNumber)) ? false : true );
       
  1159     }
       
  1160 %}
       
  1161 .
       
  1162     aNumber respondsToArithmetic ifFalse:[^ true].
       
  1163     ^ self retry:#~= coercing:aNumber
       
  1164 ! !
       
  1165 
       
  1166 !SmallInteger methodsFor:'copying'!
       
  1167 
       
  1168 deepCopy
       
  1169     "return a deep copy of myself
       
  1170      - reimplemented here since smallintegers are unique"
       
  1171 
       
  1172     ^ self
       
  1173 !
       
  1174 
       
  1175 deepCopyUsing:aDictionary
       
  1176     "return a deep copy of myself
       
  1177      - reimplemented here since smallintegers are unique"
       
  1178 
       
  1179     ^ self
       
  1180 !
       
  1181 
       
  1182 shallowCopy
       
  1183     "return a shallow copy of myself
       
  1184      - reimplemented here since smallintegers are unique"
       
  1185 
       
  1186     ^ self
       
  1187 !
       
  1188 
       
  1189 simpleDeepCopy
       
  1190     "return a deep copy of myself
       
  1191      - reimplemented here since smallintegers are unique"
       
  1192 
       
  1193     ^ self
  1387 ! !
  1194 ! !
  1388 
  1195 
  1389 !SmallInteger methodsFor:'iteration'!
  1196 !SmallInteger methodsFor:'iteration'!
  1390 
  1197 
  1391 timesRepeat:aBlock
  1198 timesRepeat:aBlock
  1523 "/        aBlock value.
  1330 "/        aBlock value.
  1524 "/        count := count - 1
  1331 "/        count := count - 1
  1525 "/    ]
  1332 "/    ]
  1526 !
  1333 !
  1527 
  1334 
  1528 to:stop do:aBlock
       
  1529     "evaluate aBlock for every integer between (and including) the receiver
       
  1530      and the argument, stop.
       
  1531      Reimplemented as primitive for speed"
       
  1532 
       
  1533     |home|
       
  1534 %{
       
  1535     REGISTER INT tmp;
       
  1536     INT final;
       
  1537     REGISTER OBJFUNC code;
       
  1538     extern OBJ Block;
       
  1539     static struct inlineCache blockVal = __ILC1(0);
       
  1540     REGISTER OBJ rHome;
       
  1541 
       
  1542     if (__isSmallInteger(stop)) {
       
  1543 	tmp = _intVal(self);
       
  1544 	final = _intVal(stop);
       
  1545 	if (__isBlockLike(aBlock)
       
  1546 	 && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) {
       
  1547 	    if ((code = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
       
  1548 #ifdef NEW_BLOCK_CALL
       
  1549 		while (tmp <= final) {
       
  1550 		    if (InterruptPending != nil) interrupt(CONARG);
       
  1551 		    (*code)(aBlock, CON_COMMA _MKSMALLINT(tmp));
       
  1552 		    tmp++;
       
  1553 		}
       
  1554 #else /* old BLOCK_CALL */
       
  1555 		/*
       
  1556 		 * arg is a compiled block - 
       
  1557 		 * directly call it without going through "Block-value"
       
  1558 		 */
       
  1559 		rHome = _BlockInstPtr(aBlock)->b_home;
       
  1560 		if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) {
       
  1561 		    /*
       
  1562 		     * home will not move - keep in in a register
       
  1563 		     * since this is also the most common case,
       
  1564 		     * its worth trading a bit memory for speed here ...
       
  1565 		     */
       
  1566 # if defined(UNROLL_LOOPS)
       
  1567 		    {
       
  1568 			int t4;
       
  1569 
       
  1570 			while ((t4 = tmp+4) < final) {
       
  1571 			    OBJ idx = _MKSMALLINT(tmp);
       
  1572 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1573 			    (*code)(rHome, CON_COMMA idx);
       
  1574 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1575 			    (*code)(rHome, CON_COMMA _ADD_INT(idx, 1));
       
  1576 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1577 			    (*code)(rHome, CON_COMMA _ADD_INT(idx,2));
       
  1578 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1579 			    (*code)(rHome, CON_COMMA _ADD_INT(idx,3));
       
  1580 			    tmp = t4;
       
  1581 			}
       
  1582 		    }
       
  1583 # endif
       
  1584 		    while (tmp <= final) {
       
  1585 			if (InterruptPending != nil) interrupt(CONARG);
       
  1586 			(*code)(rHome, CON_COMMA _MKSMALLINT(tmp));
       
  1587 			tmp++;
       
  1588 		    }
       
  1589 		} else {
       
  1590 		    home = rHome;
       
  1591 		    while (tmp <= final) {
       
  1592 			if (InterruptPending != nil) interrupt(CONARG);
       
  1593 			(*code)(home, CON_COMMA _MKSMALLINT(tmp));
       
  1594 			tmp++;
       
  1595 		    }
       
  1596 		}
       
  1597 		RETURN (self);
       
  1598 #endif /* NEW_BLOCK_CALL */
       
  1599 	    }
       
  1600 	    if (_BlockInstPtr(aBlock)->b_bytecodes != nil) {
       
  1601 		/*
       
  1602 		 * an interpreted block
       
  1603 		 */
       
  1604 #ifdef PASS_ARG_POINTER
       
  1605 		extern OBJ __interpret();
       
  1606 #else
       
  1607 		extern OBJ interpret();
       
  1608 #endif
       
  1609 		home = _BlockInstPtr(aBlock)->b_home;
       
  1610 #ifdef PASS_ARG_POINTER
       
  1611 # ifdef INDIRECT_CALL_IS_FASTER
       
  1612 		code = __interpret;
       
  1613 #  define       INTERPRET (*code)
       
  1614 # else
       
  1615 #  define       INTERPRET __interpret
       
  1616 # endif
       
  1617 #else
       
  1618 # ifdef INDIRECT_CALL_IS_FASTER
       
  1619 		code = interpret;
       
  1620 #  define       INTERPRET (*code)
       
  1621 # else
       
  1622 #  define       INTERPRET interpret
       
  1623 # endif
       
  1624 #endif
       
  1625 #ifdef NEW_BLOCK_CALL
       
  1626 # define HOME nil
       
  1627 #else
       
  1628 # define HOME home
       
  1629 #endif
       
  1630 		while (tmp <= final) {
       
  1631 
       
  1632 		    if (InterruptPending != nil) interrupt(CONARG);
       
  1633 #ifdef PASS_ARG_POINTER
       
  1634 		    {
       
  1635 		      OBJ idx;
       
  1636 		      idx = __MKSMALLINT(tmp);
       
  1637 		      INTERPRET(aBlock, 1, nil, HOME COMMA_SND, nil, &idx);
       
  1638 		    }
       
  1639 #else
       
  1640 		    INTERPRET(aBlock, 1, nil, HOME COMMA_SND, nil, __MKSMALLINT(tmp));
       
  1641 #endif
       
  1642 		    tmp++;
       
  1643 		}
       
  1644 		RETURN (self);
       
  1645 	    }
       
  1646 	}
       
  1647 	/*
       
  1648 	 * arg is something else - call it with value"
       
  1649 	 */
       
  1650 	while (tmp <= final) {
       
  1651 	    if (InterruptPending != nil) interrupt(CONARG);
       
  1652 
       
  1653 	    (*blockVal.ilc_func)(aBlock, 
       
  1654 				     @symbol(value:), 
       
  1655 				     CON_COMMA nil, &blockVal, 
       
  1656 				     _MKSMALLINT(tmp));
       
  1657 	    tmp++;
       
  1658 	}
       
  1659 	RETURN ( self );
       
  1660     }
       
  1661 %}.
       
  1662     "/
       
  1663     "/ arrive here if stop is not a smallInteger
       
  1664     "/
       
  1665 
       
  1666     ^ super to:stop do:aBlock
       
  1667 
       
  1668     "
       
  1669      1 to:10 do:[:i | i printNewline]
       
  1670     "
       
  1671 !
       
  1672 
       
  1673 to:stop by:incr do:aBlock
  1335 to:stop by:incr do:aBlock
  1674     "reimplemented as primitive for speed"
  1336     "reimplemented as primitive for speed"
  1675 
  1337 
  1676     |home|
  1338     |home|
  1677 %{
  1339 %{
  1779     ^ super to:stop by:incr do:aBlock
  1441     ^ super to:stop by:incr do:aBlock
  1780 
  1442 
  1781     "
  1443     "
  1782      1 to:10 by:3 do:[:i | i printNewline]
  1444      1 to:10 by:3 do:[:i | i printNewline]
  1783     "
  1445     "
       
  1446 !
       
  1447 
       
  1448 to:stop do:aBlock
       
  1449     "evaluate aBlock for every integer between (and including) the receiver
       
  1450      and the argument, stop.
       
  1451      Reimplemented as primitive for speed"
       
  1452 
       
  1453     |home|
       
  1454 %{
       
  1455     REGISTER INT tmp;
       
  1456     INT final;
       
  1457     REGISTER OBJFUNC code;
       
  1458     extern OBJ Block;
       
  1459     static struct inlineCache blockVal = __ILC1(0);
       
  1460     REGISTER OBJ rHome;
       
  1461 
       
  1462     if (__isSmallInteger(stop)) {
       
  1463 	tmp = _intVal(self);
       
  1464 	final = _intVal(stop);
       
  1465 	if (__isBlockLike(aBlock)
       
  1466 	 && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) {
       
  1467 	    if ((code = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) {
       
  1468 #ifdef NEW_BLOCK_CALL
       
  1469 		while (tmp <= final) {
       
  1470 		    if (InterruptPending != nil) interrupt(CONARG);
       
  1471 		    (*code)(aBlock, CON_COMMA _MKSMALLINT(tmp));
       
  1472 		    tmp++;
       
  1473 		}
       
  1474 #else /* old BLOCK_CALL */
       
  1475 		/*
       
  1476 		 * arg is a compiled block - 
       
  1477 		 * directly call it without going through "Block-value"
       
  1478 		 */
       
  1479 		rHome = _BlockInstPtr(aBlock)->b_home;
       
  1480 		if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) {
       
  1481 		    /*
       
  1482 		     * home will not move - keep in in a register
       
  1483 		     * since this is also the most common case,
       
  1484 		     * its worth trading a bit memory for speed here ...
       
  1485 		     */
       
  1486 # if defined(UNROLL_LOOPS)
       
  1487 		    {
       
  1488 			int t4;
       
  1489 
       
  1490 			while ((t4 = tmp+4) < final) {
       
  1491 			    OBJ idx = _MKSMALLINT(tmp);
       
  1492 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1493 			    (*code)(rHome, CON_COMMA idx);
       
  1494 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1495 			    (*code)(rHome, CON_COMMA _ADD_INT(idx, 1));
       
  1496 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1497 			    (*code)(rHome, CON_COMMA _ADD_INT(idx,2));
       
  1498 			    if (InterruptPending != nil) interrupt(CONARG);
       
  1499 			    (*code)(rHome, CON_COMMA _ADD_INT(idx,3));
       
  1500 			    tmp = t4;
       
  1501 			}
       
  1502 		    }
       
  1503 # endif
       
  1504 		    while (tmp <= final) {
       
  1505 			if (InterruptPending != nil) interrupt(CONARG);
       
  1506 			(*code)(rHome, CON_COMMA _MKSMALLINT(tmp));
       
  1507 			tmp++;
       
  1508 		    }
       
  1509 		} else {
       
  1510 		    home = rHome;
       
  1511 		    while (tmp <= final) {
       
  1512 			if (InterruptPending != nil) interrupt(CONARG);
       
  1513 			(*code)(home, CON_COMMA _MKSMALLINT(tmp));
       
  1514 			tmp++;
       
  1515 		    }
       
  1516 		}
       
  1517 		RETURN (self);
       
  1518 #endif /* NEW_BLOCK_CALL */
       
  1519 	    }
       
  1520 	    if (_BlockInstPtr(aBlock)->b_bytecodes != nil) {
       
  1521 		/*
       
  1522 		 * an interpreted block
       
  1523 		 */
       
  1524 #ifdef PASS_ARG_POINTER
       
  1525 		extern OBJ __interpret();
       
  1526 #else
       
  1527 		extern OBJ interpret();
       
  1528 #endif
       
  1529 		home = _BlockInstPtr(aBlock)->b_home;
       
  1530 #ifdef PASS_ARG_POINTER
       
  1531 # ifdef INDIRECT_CALL_IS_FASTER
       
  1532 		code = __interpret;
       
  1533 #  define       INTERPRET (*code)
       
  1534 # else
       
  1535 #  define       INTERPRET __interpret
       
  1536 # endif
       
  1537 #else
       
  1538 # ifdef INDIRECT_CALL_IS_FASTER
       
  1539 		code = interpret;
       
  1540 #  define       INTERPRET (*code)
       
  1541 # else
       
  1542 #  define       INTERPRET interpret
       
  1543 # endif
       
  1544 #endif
       
  1545 #ifdef NEW_BLOCK_CALL
       
  1546 # define HOME nil
       
  1547 #else
       
  1548 # define HOME home
       
  1549 #endif
       
  1550 		while (tmp <= final) {
       
  1551 
       
  1552 		    if (InterruptPending != nil) interrupt(CONARG);
       
  1553 #ifdef PASS_ARG_POINTER
       
  1554 		    {
       
  1555 		      OBJ idx;
       
  1556 		      idx = __MKSMALLINT(tmp);
       
  1557 		      INTERPRET(aBlock, 1, nil, HOME COMMA_SND, nil, &idx);
       
  1558 		    }
       
  1559 #else
       
  1560 		    INTERPRET(aBlock, 1, nil, HOME COMMA_SND, nil, __MKSMALLINT(tmp));
       
  1561 #endif
       
  1562 		    tmp++;
       
  1563 		}
       
  1564 		RETURN (self);
       
  1565 	    }
       
  1566 	}
       
  1567 	/*
       
  1568 	 * arg is something else - call it with value"
       
  1569 	 */
       
  1570 	while (tmp <= final) {
       
  1571 	    if (InterruptPending != nil) interrupt(CONARG);
       
  1572 
       
  1573 	    (*blockVal.ilc_func)(aBlock, 
       
  1574 				     @symbol(value:), 
       
  1575 				     CON_COMMA nil, &blockVal, 
       
  1576 				     _MKSMALLINT(tmp));
       
  1577 	    tmp++;
       
  1578 	}
       
  1579 	RETURN ( self );
       
  1580     }
       
  1581 %}.
       
  1582     "/
       
  1583     "/ arrive here if stop is not a smallInteger
       
  1584     "/
       
  1585 
       
  1586     ^ super to:stop do:aBlock
       
  1587 
       
  1588     "
       
  1589      1 to:10 do:[:i | i printNewline]
       
  1590     "
  1784 ! !
  1591 ! !
  1785 
  1592 
  1786 !SmallInteger class methodsFor:'binary storage'!
  1593 !SmallInteger methodsFor:'misc math'!
  1787 
  1594 
  1788 binaryDefinitionFrom: stream manager: manager
  1595 gcd:anInteger
  1789     "read the binary representation as stored in storeBinaryOn:"
  1596     "return the greatest common divisor (Euclid's algorithm).
  1790 
  1597      This has been redefined here for more speed since due to the
  1791     | value |
  1598      use of gcd in Fraction code, it has become time-critical for
  1792 
  1599      some code. (thanx to MessageTally)"
  1793     value := stream next bitAnd: 16r7F.
  1600 
  1794     value > 16r3F ifTrue: [
  1601 %{  /* NOCONTEXT */
  1795 	value := value - 16r80
  1602 
       
  1603     if (__isSmallInteger(anInteger)) {
       
  1604 	INT orgArg, ttt, selfInt, temp;
       
  1605 
       
  1606 	ttt = orgArg = _intVal(anInteger);
       
  1607 	if (ttt) {
       
  1608 	    selfInt = _intVal(self);
       
  1609 	    while (ttt != 0) {
       
  1610 		temp = selfInt % ttt;
       
  1611 		selfInt = ttt;
       
  1612 		ttt = temp;
       
  1613 	    }
       
  1614 	    /*
       
  1615 	     * since its not defined in what the sign of
       
  1616 	     * a modulu result is when the arg is negative,
       
  1617 	     * change it explicitely here ...
       
  1618 	     */
       
  1619 	    if (orgArg < 0) {
       
  1620 		/* result should be negative */
       
  1621 		if (selfInt > 0) selfInt = -selfInt;
       
  1622 	    } else {
       
  1623 		/* result should be positive */
       
  1624 		if (selfInt < 0) selfInt = -selfInt;
       
  1625 	    }
       
  1626 	    RETURN ( _MKSMALLINT(selfInt) );
       
  1627 	}
       
  1628     }
       
  1629 %}
       
  1630 .
       
  1631     ^ super gcd:anInteger
       
  1632 !
       
  1633 
       
  1634 intlog10
       
  1635     "return the truncation of log10 of the receiver -
       
  1636      stupid implementation; used to find out the number of digits needed
       
  1637      to print a number/and for conversion to a LargeInteger.
       
  1638      Implemented that way, to allow for tiny systems without a Float class
       
  1639      (i.e. without log)."
       
  1640 
       
  1641     self <= 0 ifTrue:[
       
  1642 	self error:'logarithm of negative integer'
  1796     ].
  1643     ].
  1797     value := (value bitShift: 8) bitOr: stream next.
  1644     self < 10 ifTrue:[^ 1].
  1798     value := (value bitShift: 8) bitOr: stream next.
  1645     self < 100 ifTrue:[^ 2].
  1799     value := (value bitShift: 8) bitOr: stream next.
  1646     self < 1000 ifTrue:[^ 3].
  1800     ^ value
  1647     self < 10000 ifTrue:[^ 4].
       
  1648     self < 100000 ifTrue:[^ 5].
       
  1649     self < 1000000 ifTrue:[^ 6].
       
  1650     self < 10000000 ifTrue:[^ 7].
       
  1651     self < 100000000 ifTrue:[^ 8].
       
  1652     self < 1000000000 ifTrue:[^ 9].
       
  1653     ^ 10
  1801 ! !
  1654 ! !
  1802 
  1655 
  1803 !SmallInteger methodsFor:'binary storage'!
  1656 !SmallInteger methodsFor:'modulu arithmetic'!
  1804 
  1657 
  1805 hasSpecialBinaryRepresentation
  1658 plus:aNumber
  1806     "return true, if the receiver has a special binary representation"
  1659     "return the sum of the receiver and the argument, as SmallInteger.
  1807 
  1660      The argument must be another SmallInteger.
  1808     ^ true
  1661      If the result overflows the smallInteger range, the value modulu the 
  1809 !
  1662      smallInteger range is returned (i.e. the low bits of the sum).
  1810 
  1663      This is of course not always correct, but some code does a modulu anyway
  1811 storeBinaryOn: stream manager: manager
  1664      and can therefore speed things up by not going through LargeIntegers."
  1812     "append a binary representation onto stream.
  1665 
  1813      Redefined since SmallIntegers are stored as their value with the 32nd bit 
  1666 %{  /* NOCONTEXT */
  1814      set as a tag.
  1667 
  1815      To make the binary file a bit more compact, zeros and single byte ints
  1668     if (__isSmallInteger(aNumber)) {
  1816      are stored with a more compact representation (using special type-codes)."
  1669 	RETURN ( _MKSMALLINT((_intVal(self) + _intVal(aNumber)) & 0x7FFFFFFF) );
  1817 
  1670     }
  1818     self == 0 ifTrue:[
  1671 %}
  1819 	stream nextPut: manager codeForZero.
  1672 .
  1820 	^ self
  1673     self primitiveFailed
  1821     ].
  1674 !
  1822     (self between:0 and:255) ifTrue:[
  1675 
  1823 	stream nextPut: manager codeForByteInteger.
  1676 subtract:aNumber
  1824 	stream nextPut: self.
  1677     "return the difference of the receiver and the argument, as SmallInteger.
  1825 	^ self
  1678      The argument must be another SmallInteger.
  1826     ].
  1679      If the result overflows the smallInteger range, the value modulu the 
  1827     stream nextPut: (((self bitShift: -24) bitAnd: 16rFF) bitOr: 16r80).
  1680      smallInteger range is returned (i.e. the low bits of the sum).
  1828     stream nextPut: ((self bitShift: -16) bitAnd: 16rFF).
  1681      This is of course not always correct, but some code does a modulu anyway
  1829     stream nextPut: ((self bitShift: -8) bitAnd: 16rFF).
  1682      and can therefore speed things up by not going through LargeIntegers."
  1830     stream nextPut: (self bitAnd: 16rFF)
  1683 
       
  1684 %{  /* NOCONTEXT */
       
  1685 
       
  1686     if (__isSmallInteger(aNumber)) {
       
  1687 	RETURN ( _MKSMALLINT((_intVal(self) - _intVal(aNumber)) & 0x7FFFFFFF) );
       
  1688     }
       
  1689 %}
       
  1690 .
       
  1691     self primitiveFailed
       
  1692 !
       
  1693 
       
  1694 times:aNumber
       
  1695     "return the product of the receiver and the argument, as SmallInteger.
       
  1696      The argument must be another SmallInteger.
       
  1697      If the result overflows the smallInteger range, the value modulu the 
       
  1698      smallInteger range is returned (i.e. the low bits of the product).
       
  1699      This is of course not always correct, but some code does a modulu anyway
       
  1700      and can therefore speed things up by not going through LargeIntegers."
       
  1701 
       
  1702 %{  /* NOCONTEXT */
       
  1703 
       
  1704     if (__isSmallInteger(aNumber)) {
       
  1705 	RETURN ( _MKSMALLINT((_intVal(self) * _intVal(aNumber)) & 0x7FFFFFFF) );
       
  1706     }
       
  1707 %}
       
  1708 .
       
  1709     self primitiveFailed
  1831 ! !
  1710 ! !
  1832 
  1711 
  1833 !SmallInteger methodsFor:'printing & storing'!
  1712 !SmallInteger methodsFor:'printing & storing'!
  1834 
  1713 
  1835 printOn:aStream
  1714 printOn:aStream
  1836     "append my printstring (base 10) to aStream."
  1715     "append my printstring (base 10) to aStream."
  1837 
  1716 
  1838     aStream nextPutAll:(self printString)
  1717     aStream nextPutAll:(self printString)
       
  1718 !
       
  1719 
       
  1720 printOn:aStream base:radix
       
  1721     "append my printstring in any number base to aStream.
       
  1722      The radix argument should be between 2 and 36."
       
  1723 
       
  1724     aStream nextPutAll:(self printStringRadix:radix)
  1839 !
  1725 !
  1840 
  1726 
  1841 printString
  1727 printString
  1842     "return my printstring (base 10)"
  1728     "return my printstring (base 10)"
  1843 
  1729 
  1869     if (newString != nil) {
  1755     if (newString != nil) {
  1870 	RETURN (newString);
  1756 	RETURN (newString);
  1871     }
  1757     }
  1872 %}.
  1758 %}.
  1873     ^ super printString
  1759     ^ super printString
  1874 !
       
  1875 
       
  1876 printOn:aStream base:radix
       
  1877     "append my printstring in any number base to aStream.
       
  1878      The radix argument should be between 2 and 36."
       
  1879 
       
  1880     aStream nextPutAll:(self printStringRadix:radix)
       
  1881 !
  1760 !
  1882 
  1761 
  1883 printStringRadix:radix
  1762 printStringRadix:radix
  1884     "return my printstring (optimized for bases 16, 10 and 8)"
  1763     "return my printstring (optimized for bases 16, 10 and 8)"
  1885 
  1764 
  1977     "123 printfPrintString:'%%6d -> %6d'"
  1856     "123 printfPrintString:'%%6d -> %6d'"
  1978     "123 printfPrintString:'%%x -> %x'"
  1857     "123 printfPrintString:'%%x -> %x'"
  1979     "123 printfPrintString:'%%4x -> %4x'"
  1858     "123 printfPrintString:'%%4x -> %4x'"
  1980     "123 printfPrintString:'%%04x -> %04x'"
  1859     "123 printfPrintString:'%%04x -> %04x'"
  1981 ! !
  1860 ! !
       
  1861 
       
  1862 !SmallInteger methodsFor:'testing'!
       
  1863 
       
  1864 between:min and:max
       
  1865     "return true if the receiver is less than or equal to the argument max
       
  1866      and greater than or equal to the argument min.
       
  1867      - reimplemented here for speed"
       
  1868 
       
  1869 %{  /* NOCONTEXT */
       
  1870 
       
  1871     if (__bothSmallInteger(min, max)) {
       
  1872 	REGISTER INT selfVal;
       
  1873 
       
  1874 	selfVal = _intVal(self);
       
  1875 	if (selfVal < _intVal(min)) {
       
  1876 	     RETURN ( false );
       
  1877 	}
       
  1878 	if (selfVal > _intVal(max)) {
       
  1879 	     RETURN ( false );
       
  1880 	}
       
  1881 	RETURN ( true );
       
  1882     }
       
  1883 %}
       
  1884 .
       
  1885     (self < min) ifTrue:[^ false].
       
  1886     (self > max) ifTrue:[^ false].
       
  1887     ^ true
       
  1888 !
       
  1889 
       
  1890 even
       
  1891     "return true, if the receiver is even"
       
  1892 
       
  1893 %{  /* NOCONTEXT */
       
  1894 
       
  1895 #ifdef POSITIVE_ADDRESSES
       
  1896     RETURN ( ((INT)self & 1) ? false : true );
       
  1897 #else    
       
  1898     RETURN ( ((INT)self & ((INT)_MKSMALLINT(1) & ~TAG_INT)) ? false : true );
       
  1899 #endif
       
  1900 %}
       
  1901 !
       
  1902 
       
  1903 negative
       
  1904     "return true, if the receiver is less than zero
       
  1905      reimplemented here for speed"
       
  1906 
       
  1907 %{  /* NOCONTEXT */
       
  1908 
       
  1909 #ifdef POSITIVE_ADDRESSES
       
  1910     RETURN ( (_intVal(self) < 0) ? true : false );
       
  1911 #else
       
  1912     /* tag bit does not change sign */
       
  1913     RETURN ( ((INT)(self) < 0) ? true : false );
       
  1914 #endif
       
  1915 %}
       
  1916 !
       
  1917 
       
  1918 odd
       
  1919     "return true, if the receiver is odd"
       
  1920 
       
  1921 %{  /* NOCONTEXT */
       
  1922 
       
  1923 #ifdef POSITIVE_ADDRESSES
       
  1924     RETURN ( ((INT)self & 1) ? true : false );
       
  1925 #else    
       
  1926     RETURN ( ((INT)self & ((INT)_MKSMALLINT(1) & ~TAG_INT)) ? true : false );
       
  1927 #endif
       
  1928 %}
       
  1929 !
       
  1930 
       
  1931 positive
       
  1932     "return true, if the receiver is not negative
       
  1933      reimplemented here for speed"
       
  1934 
       
  1935 %{  /* NOCONTEXT */
       
  1936 
       
  1937 #ifdef POSITIVE_ADDRESSES
       
  1938     RETURN ( (_intVal(self) >= 0) ? true : false );
       
  1939 #else
       
  1940     /* tag bit does not change sign */
       
  1941     RETURN ( ((INT)(self) >= 0) ? true : false );
       
  1942 #endif
       
  1943 %}
       
  1944 !
       
  1945 
       
  1946 sign
       
  1947     "return the sign of the receiver
       
  1948      reimplemented here for speed"
       
  1949 
       
  1950 %{  /* NOCONTEXT */
       
  1951 
       
  1952     INT val = _intVal(self);
       
  1953 
       
  1954     if (val < 0) {
       
  1955 	RETURN ( _MKSMALLINT(-1) ); 
       
  1956     }
       
  1957     if (val > 0) {
       
  1958 	RETURN ( _MKSMALLINT(1) );
       
  1959     }
       
  1960     RETURN ( _MKSMALLINT(0) );
       
  1961 %}
       
  1962 !
       
  1963 
       
  1964 strictlyPositive
       
  1965     "return true, if the receiver is greater than zero
       
  1966      reimplemented here for speed"
       
  1967 
       
  1968 %{  /* NOCONTEXT */
       
  1969 
       
  1970 #ifdef POSITIVE_ADDRESSES
       
  1971     RETURN ( (_intVal(self) > 0) ? true : false );
       
  1972 #else
       
  1973     /* tag bit does not change sign */
       
  1974     RETURN ( ((INT)(self) > 0) ? true : false );
       
  1975 #endif
       
  1976 %}
       
  1977 ! !
       
  1978 
       
  1979 !SmallInteger class methodsFor:'documentation'!
       
  1980 
       
  1981 version
       
  1982     ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.40 1995-12-07 21:36:33 cg Exp $'
       
  1983 ! !