MCPcopy Index your code
hub / github.com/python/cpython / _dec_str_to_int_inner

Function _dec_str_to_int_inner

Lib/_pylong.py:271–387  ·  view source on GitHub ↗
(s, *, GUARD=8)

Source from the content-addressed store, hash-verified

269del defaultdict
270
271def _dec_str_to_int_inner(s, *, GUARD=8):
272 # Yes, BYTELIM is "large". Large enough that CPython will usually
273 # use the Karatsuba _str_to_int_inner to convert the string. This
274 # allowed reducing the cutoff for calling _this_ function from 3.5M
275 # to 2M digits. We could almost certainly do even better by
276 # fine-tuning this and/or using a larger output base than 256.
277 BYTELIM = 100_000
278 D = decimal.Decimal
279 result = bytearray()
280 # See notes at end of file for discussion of GUARD.
281 assert GUARD > 0 # if 0, `decimal` can blow up - .prec 0 not allowed
282
283 def inner(n, w):
284 #assert n < D256 ** w # required, but too expensive to check
285 if w <= BYTELIM:
286 # XXX Stefan Pochmann discovered that, for 1024-bit ints,
287 # `int(Decimal)` took 2.5x longer than `int(str(Decimal))`.
288 # Worse, `int(Decimal) is still quadratic-time for much
289 # larger ints. So unless/until all that is repaired, the
290 # seemingly redundant `str(Decimal)` is crucial to speed.
291 result.extend(int(str(n)).to_bytes(w)) # big-endian default
292 return
293 w1 = w >> 1
294 w2 = w - w1
295 if 0:
296 # This is maximally clear, but "too slow". `decimal`
297 # division is asymptotically fast, but we have no way to
298 # tell it to reuse the high-precision reciprocal it computes
299 # for pow256[w2], so it has to recompute it over & over &
300 # over again :-(
301 hi, lo = divmod(n, pow256[w2][0])
302 else:
303 p256, recip = pow256[w2]
304 # The integer part will have a number of digits about equal
305 # to the difference between the log10s of `n` and `pow256`
306 # (which, since these are integers, is roughly approximated
307 # by `.adjusted()`). That's the working precision we need,
308 ctx.prec = max(n.adjusted() - p256.adjusted(), 0) + GUARD
309 hi = +n * +recip # unary `+` chops back to ctx.prec digits
310 ctx.prec = decimal.MAX_PREC
311 hi = hi.to_integral_value() # lose the fractional digits
312 lo = n - hi * p256
313 # Because we've been uniformly rounding down, `hi` is a
314 # lower bound on the correct quotient.
315 assert lo >= 0
316 # Adjust quotient up if needed. It usually isn't. In random
317 # testing on inputs through 5 billion digit strings, the
318 # test triggered once in about 200 thousand tries.
319 count = 0
320 if lo >= p256:
321 count = 1
322 lo -= p256
323 hi += 1
324 if lo >= p256:
325 # Complete correction via an exact computation. I
326 # believe it's not possible to get here provided
327 # GUARD >= 3. It's tested by reducing GUARD below
328 # that.

Callers

nothing calls this directly

Calls 7

DClass · 0.90
compute_powersFunction · 0.85
bit_lengthMethod · 0.80
adjustedMethod · 0.80
innerFunction · 0.70
__len__Method · 0.45
itemsMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…