|
|
@@ -99,11 +99,38 @@ def ulong_divmodi(a: list, b: int):
|
|
|
ulong_unpad_(res)
|
|
|
return res, carry
|
|
|
|
|
|
+
|
|
|
def ulong_divmod(a: list, b: list):
|
|
|
- q = [0]
|
|
|
- while ulong_cmp(a, b) >= 0:
|
|
|
- ulong_inc_(q)
|
|
|
- a = ulong_sub(a, b)
|
|
|
+
|
|
|
+ if ulong_cmp(a, b) < 0:
|
|
|
+ return [0], a
|
|
|
+
|
|
|
+ if len(b) == 1:
|
|
|
+ q, r = ulong_divmodi(a, b[0])
|
|
|
+ r, _ = ulong_fromint(r)
|
|
|
+ return q, r
|
|
|
+
|
|
|
+ max = (len(a) - len(b)) * PyLong_SHIFT + \
|
|
|
+ (a[-1].bit_length() - b[-1].bit_length())
|
|
|
+
|
|
|
+ low = [0]
|
|
|
+
|
|
|
+ high = (max // PyLong_SHIFT) * [0] + \
|
|
|
+ [(2**(max % PyLong_SHIFT)) & PyLong_MASK]
|
|
|
+
|
|
|
+ while ulong_cmp(low, high) < 0:
|
|
|
+ ulong_inc_(high)
|
|
|
+ mid, r = ulong_divmodi(ulong_add(low, high), 2)
|
|
|
+ if ulong_cmp(a, ulong_mul(b, mid)) >= 0:
|
|
|
+ low = mid
|
|
|
+ else:
|
|
|
+ high = ulong_sub(mid, [1])
|
|
|
+
|
|
|
+ q = [0] * (len(a) - len(b) + 1)
|
|
|
+ while ulong_cmp(a, ulong_mul(b, low)) >= 0:
|
|
|
+ q = ulong_add(q, low)
|
|
|
+ a = ulong_sub(a, ulong_mul(b, low))
|
|
|
+ ulong_unpad_(q)
|
|
|
return q, a
|
|
|
|
|
|
def ulong_floordivi(a: list, b: int):
|