LargeInteger.st
changeset 1717 0db1dbfc057d
parent 1556 134d96466f5a
child 1794 c8f7736d1c12
equal deleted inserted replaced
1716:52fc3e02c5bd 1717:0db1dbfc057d
    81     "catch creation message"
    81     "catch creation message"
    82 
    82 
    83     self error:'LargeIntegers cannot be created with new'
    83     self error:'LargeIntegers cannot be created with new'
    84 !
    84 !
    85 
    85 
    86 sign:s value16:ll value16:ml value16:mh value16:hh
       
    87     "create and return a new LargeInteger, with value taken from the
       
    88      four 16-bit unsigned value-args.
       
    89      This is sent internally, when a 64bit result has been created in
       
    90      SmallInteger multiplication or bitShift:.
       
    91      May change without notice."
       
    92 
       
    93     |newLarge digitBytes 
       
    94      hhI "{ Class: SmallInteger }"
       
    95      mhI "{ Class: SmallInteger }"
       
    96      mlI "{ Class: SmallInteger }"
       
    97      llI "{ Class: SmallInteger }"
       
    98      b1 "{ Class: SmallInteger }"
       
    99      b2 "{ Class: SmallInteger }"
       
   100      b3 "{ Class: SmallInteger }"
       
   101      b4 "{ Class: SmallInteger }"
       
   102      b5 "{ Class: SmallInteger }"
       
   103      b6 "{ Class: SmallInteger }"
       
   104      b7 "{ Class: SmallInteger }"
       
   105      b8 "{ Class: SmallInteger }"
       
   106      n "{ Class: SmallInteger }"|
       
   107 
       
   108     "
       
   109      this will change, once arguments can have a type-constraint
       
   110     "
       
   111     hhI := hh.
       
   112     mhI := mh.
       
   113     mlI := ml.
       
   114     llI := ll.
       
   115 
       
   116     "
       
   117      the following code is somewhat ugly, but includes an unrolled
       
   118      normalization, and is thus relatively fast ....
       
   119     "
       
   120     b8 := (hh bitShift:-8) bitAnd:16rFF.
       
   121     b7 := hh bitAnd:16rFF.
       
   122     b6 := (mh bitShift:-8) bitAnd:16rFF.
       
   123     b5 := mh bitAnd:16rFF.
       
   124     b4 := (ml bitShift:-8) bitAnd:16rFF.
       
   125     b3 := ml bitAnd:16rFF.
       
   126     b2 := (ll bitShift:-8) bitAnd:16rFF.
       
   127     b1 := ll bitAnd:16rFF.
       
   128 
       
   129     b8 ~~ 0 ifTrue:[
       
   130 	n := 8
       
   131     ] ifFalse:[
       
   132 	b7 ~~ 0 ifTrue:[
       
   133 	    n := 7.
       
   134 	] ifFalse:[
       
   135 	    b6 ~~ 0 ifTrue:[
       
   136 		n := 6.
       
   137 	    ] ifFalse:[
       
   138 		b5 ~~ 0 ifTrue:[
       
   139 		    n := 5
       
   140 		] ifFalse:[
       
   141 		    b4 ~~ 0 ifTrue:[
       
   142 			n := 4
       
   143 		    ] ifFalse:[
       
   144 			b3 ~~ 0 ifTrue:[
       
   145 			    n := 3
       
   146 			] ifFalse:[
       
   147 			    b2 ~~ 0 ifTrue:[
       
   148 				n := 2
       
   149 			    ] ifFalse:[
       
   150 				n := 1
       
   151 			    ]
       
   152 			]
       
   153 		    ]
       
   154 		]
       
   155 	    ]
       
   156 	]
       
   157     ].
       
   158         
       
   159         
       
   160     digitBytes := ByteArray uninitializedNew:n.
       
   161     digitBytes at:1 put:b1.
       
   162     n > 1 ifTrue:[
       
   163 	digitBytes at:2 put:b2.
       
   164 	n > 2 ifTrue:[
       
   165 	    digitBytes at:3 put:b3.
       
   166 	    n > 3 ifTrue:[
       
   167 		digitBytes at:4 put:b4.
       
   168 		n > 4 ifTrue:[
       
   169 		    digitBytes at:5 put:b5.
       
   170 		    n > 5 ifTrue:[
       
   171 			digitBytes at:6 put:b6.
       
   172 			n > 6 ifTrue:[
       
   173 			    digitBytes at:7 put:b7.
       
   174 			    n > 7 ifTrue:[
       
   175 				digitBytes at:8 put:b8.
       
   176 			    ]
       
   177 			]
       
   178 		    ]
       
   179 		]
       
   180 	    ]
       
   181 	]
       
   182     ].
       
   183 
       
   184     newLarge := self basicNew setDigits:digitBytes.
       
   185     s < 0 ifTrue:[newLarge sign:s].
       
   186     ^ newLarge
       
   187 !
       
   188 
       
   189 unsignedValueLow:lowBits hi:hiBits
       
   190     "create and return a new LargeInteger with value taken from
       
   191      the two 16-bit unsigned args. 
       
   192      The largeinteger is normalized (but not to a smallInteger).
       
   193      This method is called from the runtime system (+, -),
       
   194      when an integer result has to be converted to a Large.
       
   195      May change without notice."
       
   196 
       
   197     |bytes b1 b2 b3 b4|
       
   198 
       
   199     b4 := (hiBits bitShift:-8) bitAnd:16rFF.
       
   200     b3 := hiBits bitAnd:16rFF.
       
   201     b2 := (lowBits bitShift:-8) bitAnd:16rFF.
       
   202     b1 := lowBits bitAnd:16rFF.
       
   203 
       
   204     b4 ~~ 0 ifTrue:[
       
   205 	bytes := ByteArray with:b1 with:b2 with:b3 with:b4
       
   206     ] ifFalse:[
       
   207 	b3 ~~ 0 ifTrue:[
       
   208 	    bytes := ByteArray with:b1 with:b2 with:b3
       
   209 	] ifFalse:[
       
   210 	    b2 ~~ 0 ifTrue:[
       
   211 		bytes := ByteArray with:b1 with:b2
       
   212 	    ] ifFalse:[
       
   213 		bytes := ByteArray with:b1
       
   214 	    ]
       
   215 	]
       
   216     ].
       
   217     ^ (self basicNew) setDigits:bytes
       
   218 !
       
   219 
       
   220 value:aSmallInteger
    86 value:aSmallInteger
   221     "create and return a new LargeInteger with value taken from
    87     "create and return a new LargeInteger with value taken from
   222      the argument, aSmallInteger.
    88      the argument, aSmallInteger.
   223      Notice: this should be only used internally, since such small
    89      Notice: this should be only used internally, since such small
   224      largeIntegers do not normally occur in the system.
    90      largeIntegers do not normally occur in the system.
   225      May change without notice."
    91      May change without notice."
   226 
    92 
   227     ^ self basicNew value:aSmallInteger
    93     ^ self basicNew value:aSmallInteger
   228 
    94 
   229     "LargeInteger value:3689"
    95     "LargeInteger value:3689"
   230 !
       
   231 
       
   232 valueLow:lowBits hi:hiBits
       
   233     "create and return a new LargeInteger with value taken from
       
   234      the two 16-bit args, where the sign of the high bits determines
       
   235      the sign of the result. 
       
   236      The largeinteger is normalized (but not to a smallInteger).
       
   237      This method is called from the runtime system (+, -),
       
   238      when an integer result has to be converted to a Large.
       
   239      May change without notice."
       
   240 
       
   241     |newLarge|
       
   242 
       
   243     hiBits < 0 ifTrue:[
       
   244 	newLarge := self unsignedValueLow:lowBits hi:(hiBits negated).
       
   245 	newLarge sign:-1.
       
   246 	^ newLarge
       
   247     ].
       
   248     ^ self unsignedValueLow:lowBits hi:hiBits
       
   249 ! !
    96 ! !
   250 
    97 
   251 !LargeInteger  class methodsFor:'queries'!
    98 !LargeInteger  class methodsFor:'queries'!
   252 
    99 
   253 isBuiltInClass
   100 isBuiltInClass
  1361      len1   "{ Class: SmallInteger }"
  1208      len1   "{ Class: SmallInteger }"
  1362      len2   "{ Class: SmallInteger }"
  1209      len2   "{ Class: SmallInteger }"
  1363      index  "{ Class: SmallInteger }"
  1210      index  "{ Class: SmallInteger }"
  1364      borrow "{ Class: SmallInteger }"
  1211      borrow "{ Class: SmallInteger }"
  1365      diff   "{ Class: SmallInteger }"
  1212      diff   "{ Class: SmallInteger }"
  1366      sum    "{ Class: SmallInteger }"
       
  1367      carry  "{ Class: SmallInteger }" 
  1213      carry  "{ Class: SmallInteger }" 
  1368      lResult|
  1214      lResult|
  1369 
  1215 
  1370     len1 := digitByteArray size.
  1216     len1 := digitByteArray size.
  1371     otherDigitByteArray := aLargeInteger digits.
  1217     otherDigitByteArray := aLargeInteger digits.
  1641 ! !
  1487 ! !
  1642 
  1488 
  1643 !LargeInteger  class methodsFor:'documentation'!
  1489 !LargeInteger  class methodsFor:'documentation'!
  1644 
  1490 
  1645 version
  1491 version
  1646     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.30 1996-07-18 10:31:46 cg Exp $'
  1492     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.31 1996-10-12 18:45:52 cg Exp $'
  1647 ! !
  1493 ! !