466 // aNumber |
466 // aNumber |
467 "return the quotient of the receiver and the argument, aNumber. |
467 "return the quotient of the receiver and the argument, aNumber. |
468 The result is truncated toward negative infinity and negative, |
468 The result is truncated toward negative infinity and negative, |
469 if the operands signs differ. |
469 if the operands signs differ. |
470 The following is always true: |
470 The following is always true: |
471 (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver |
471 (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver |
472 " |
472 " |
473 |
473 |
474 |cls divMod quo abs "{ Class: SmallInteger }" n| |
474 |cls divMod quo abs "{ Class: SmallInteger }" n| |
475 |
475 |
476 |
476 |
479 " |
479 " |
480 this is the common case, dividing by a SmallInteger. |
480 this is the common case, dividing by a SmallInteger. |
481 Use a special method for this case ... |
481 Use a special method for this case ... |
482 " |
482 " |
483 (cls == SmallInteger) ifTrue:[ |
483 (cls == SmallInteger) ifTrue:[ |
484 abs := aNumber. |
484 abs := aNumber. |
485 abs := abs abs. |
485 abs := abs abs. |
486 (abs between:1 and:16r00ffffff) ifTrue:[ |
486 (abs between:1 and:16r00ffffff) ifTrue:[ |
487 divMod := self absFastDivMod:abs. |
487 divMod := self absFastDivMod:abs. |
488 ] ifFalse:[ |
488 ] ifFalse:[ |
489 n := abs asLargeInteger. |
489 n := abs asLargeInteger. |
490 ]. |
490 ]. |
491 ] ifFalse:[ |
491 ] ifFalse:[ |
492 " |
492 " |
493 if the argument is not a largeInteger, coerce |
493 if the argument is not a largeInteger, coerce |
494 " |
494 " |
495 (cls == self class) ifFalse:[ |
495 (cls == self class) ifFalse:[ |
496 ^ self retry:#// coercing:aNumber |
496 ^ self retry:#// coercing:aNumber |
497 ]. |
497 ]. |
498 n := aNumber |
498 n := aNumber |
499 ]. |
499 ]. |
500 |
500 |
501 divMod isNil ifTrue:[ |
501 divMod isNil ifTrue:[ |
502 divMod := self absDivMod:n. |
502 divMod := self absDivMod:n. |
503 ]. |
503 ]. |
504 quo := divMod at:1. |
504 quo := divMod at:1. |
505 (sign == aNumber sign) ifFalse:[ |
505 (sign == aNumber sign) ifFalse:[ |
506 "/ adjust for truncation if negative and there is a remainder ... |
506 "/ adjust for truncation if negative and there is a remainder ... |
507 quo := quo sign:-1. |
507 "/ be careful: there is one special case to care for here: |
508 (divMod at:2) == 0 ifFalse:[ |
508 "/ if quo is maxInt+1, the negation can be represented as a smallInt. |
509 ^ quo - 1 |
509 quo := quo sign:-1. |
510 ]. |
510 (divMod at:2) == 0 ifFalse:[ |
|
511 ^ quo - 1 |
|
512 ]. |
|
513 quo digitLength == SmallInteger maxBytes ifTrue:[ |
|
514 ^ quo compressed |
|
515 ]. |
511 ]. |
516 ]. |
512 ^ quo |
517 ^ quo |
513 |
518 |
514 " |
519 " |
515 (9000000000 // 4000000000) = (900 // 400) ifFalse:[self halt]. |
520 (9000000000 // 4000000000) = (900 // 400) ifFalse:[self halt]. |