LargeInteger.st
changeset 12747 0b1eae8de7a4
parent 12746 10866527a1ab
child 12877 be732e8f6914
equal deleted inserted replaced
12746:10866527a1ab 12747:0b1eae8de7a4
   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].
  4943 ! !
  4948 ! !
  4944 
  4949 
  4945 !LargeInteger class methodsFor:'documentation'!
  4950 !LargeInteger class methodsFor:'documentation'!
  4946 
  4951 
  4947 version
  4952 version
  4948     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.198 2010-02-26 20:06:04 cg Exp $'
  4953     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.199 2010-02-26 20:20:38 cg Exp $'
  4949 !
  4954 !
  4950 
  4955 
  4951 version_CVS
  4956 version_CVS
  4952     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.198 2010-02-26 20:06:04 cg Exp $'
  4957     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.199 2010-02-26 20:20:38 cg Exp $'
  4953 ! !
  4958 ! !