@@ -1670,6 +1670,35 @@ divrem1(PyLongObject *a, digit n, digit *prem)
1670
1670
return long_normalize (z );
1671
1671
}
1672
1672
1673
+ /* Remainder of long pin, w/ size digits, by non-zero digit n,
1674
+ returning the remainder. pin points at the LSD. */
1675
+
1676
+ static digit
1677
+ inplace_rem1 (digit * pin , Py_ssize_t size , digit n )
1678
+ {
1679
+ twodigits rem = 0 ;
1680
+
1681
+ assert (n > 0 && n <= PyLong_MASK );
1682
+ while (-- size >= 0 )
1683
+ rem = ((rem << PyLong_SHIFT ) | pin [size ]) % n ;
1684
+ return (digit )rem ;
1685
+ }
1686
+
1687
+ /* Get the remainder of an integer divided by a digit, returning
1688
+ the remainder as the result of the function. The sign of a is
1689
+ ignored; n should not be zero. */
1690
+
1691
+ static PyLongObject *
1692
+ rem1 (PyLongObject * a , digit n )
1693
+ {
1694
+ const Py_ssize_t size = Py_ABS (Py_SIZE (a ));
1695
+
1696
+ assert (n > 0 && n <= PyLong_MASK );
1697
+ return (PyLongObject * )PyLong_FromLong (
1698
+ (long )inplace_rem1 (a -> ob_digit , size , n )
1699
+ );
1700
+ }
1701
+
1673
1702
/* Convert an integer to a base 10 string. Returns a new non-shared
1674
1703
string. (Return value is non-shared so that callers can modify the
1675
1704
returned value if necessary.) */
@@ -2689,6 +2718,47 @@ long_divrem(PyLongObject *a, PyLongObject *b,
2689
2718
return 0 ;
2690
2719
}
2691
2720
2721
+ /* Int remainder, top-level routine */
2722
+
2723
+ static int
2724
+ long_rem (PyLongObject * a , PyLongObject * b , PyLongObject * * prem )
2725
+ {
2726
+ Py_ssize_t size_a = Py_ABS (Py_SIZE (a )), size_b = Py_ABS (Py_SIZE (b ));
2727
+
2728
+ if (size_b == 0 ) {
2729
+ PyErr_SetString (PyExc_ZeroDivisionError ,
2730
+ "integer modulo by zero" );
2731
+ return -1 ;
2732
+ }
2733
+ if (size_a < size_b ||
2734
+ (size_a == size_b &&
2735
+ a -> ob_digit [size_a - 1 ] < b -> ob_digit [size_b - 1 ])) {
2736
+ /* |a| < |b|. */
2737
+ * prem = (PyLongObject * )long_long ((PyObject * )a );
2738
+ return - (* prem == NULL );
2739
+ }
2740
+ if (size_b == 1 ) {
2741
+ * prem = rem1 (a , b -> ob_digit [0 ]);
2742
+ if (* prem == NULL )
2743
+ return -1 ;
2744
+ }
2745
+ else {
2746
+ /* Slow path using divrem. */
2747
+ x_divrem (a , b , prem );
2748
+ if (* prem == NULL )
2749
+ return -1 ;
2750
+ }
2751
+ /* Set the sign. */
2752
+ if (Py_SIZE (a ) < 0 && Py_SIZE (* prem ) != 0 ) {
2753
+ _PyLong_Negate (prem );
2754
+ if (* prem == NULL ) {
2755
+ Py_CLEAR (* prem );
2756
+ return -1 ;
2757
+ }
2758
+ }
2759
+ return 0 ;
2760
+ }
2761
+
2692
2762
/* Unsigned int division with remainder -- the algorithm. The arguments v1
2693
2763
and w1 should satisfy 2 <= Py_ABS(Py_SIZE(w1)) <= Py_ABS(Py_SIZE(v1)). */
2694
2764
@@ -3814,6 +3884,37 @@ l_divmod(PyLongObject *v, PyLongObject *w,
3814
3884
return 0 ;
3815
3885
}
3816
3886
3887
+ /* Compute
3888
+ * *pmod = v % w
3889
+ * pmod cannot be NULL. The caller owns a reference to pmod.
3890
+ */
3891
+ static int
3892
+ l_mod (PyLongObject * v , PyLongObject * w , PyLongObject * * pmod )
3893
+ {
3894
+ PyLongObject * mod ;
3895
+
3896
+ assert (pmod );
3897
+ if (Py_ABS (Py_SIZE (v )) == 1 && Py_ABS (Py_SIZE (w )) == 1 ) {
3898
+ /* Fast path for single-digit longs */
3899
+ * pmod = (PyLongObject * )fast_mod (v , w );
3900
+ return - (* pmod == NULL );
3901
+ }
3902
+ if (long_rem (v , w , & mod ) < 0 )
3903
+ return -1 ;
3904
+ if ((Py_SIZE (mod ) < 0 && Py_SIZE (w ) > 0 ) ||
3905
+ (Py_SIZE (mod ) > 0 && Py_SIZE (w ) < 0 )) {
3906
+ PyLongObject * temp ;
3907
+ temp = (PyLongObject * ) long_add (mod , w );
3908
+ Py_DECREF (mod );
3909
+ mod = temp ;
3910
+ if (mod == NULL )
3911
+ return -1 ;
3912
+ }
3913
+ * pmod = mod ;
3914
+
3915
+ return 0 ;
3916
+ }
3917
+
3817
3918
static PyObject *
3818
3919
long_div (PyObject * a , PyObject * b )
3819
3920
{
@@ -4100,11 +4201,7 @@ long_mod(PyObject *a, PyObject *b)
4100
4201
4101
4202
CHECK_BINOP (a , b );
4102
4203
4103
- if (Py_ABS (Py_SIZE (a )) == 1 && Py_ABS (Py_SIZE (b )) == 1 ) {
4104
- return fast_mod ((PyLongObject * )a , (PyLongObject * )b );
4105
- }
4106
-
4107
- if (l_divmod ((PyLongObject * )a , (PyLongObject * )b , NULL , & mod ) < 0 )
4204
+ if (l_mod ((PyLongObject * )a , (PyLongObject * )b , & mod ) < 0 )
4108
4205
mod = NULL ;
4109
4206
return (PyObject * )mod ;
4110
4207
}
@@ -4333,10 +4430,10 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
4333
4430
while the "large exponent" case multiplies directly by base 31
4334
4431
times. It can be unboundedly faster to multiply by
4335
4432
base % modulus instead.
4336
- We could _always_ do this reduction, but l_divmod () isn't cheap,
4433
+ We could _always_ do this reduction, but l_mod () isn't cheap,
4337
4434
so we only do it when it buys something. */
4338
4435
if (Py_SIZE (a ) < 0 || Py_SIZE (a ) > Py_SIZE (c )) {
4339
- if (l_divmod (a , c , NULL , & temp ) < 0 )
4436
+ if (l_mod (a , c , & temp ) < 0 )
4340
4437
goto Error ;
4341
4438
Py_DECREF (a );
4342
4439
a = temp ;
@@ -4357,7 +4454,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
4357
4454
#define REDUCE (X ) \
4358
4455
do { \
4359
4456
if (c != NULL) { \
4360
- if (l_divmod (X, c, NULL, &temp) < 0) \
4457
+ if (l_mod (X, c, &temp) < 0) \
4361
4458
goto Error; \
4362
4459
Py_XDECREF(X); \
4363
4460
X = temp; \
@@ -5022,7 +5119,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
5022
5119
5023
5120
if (k == 0 ) {
5024
5121
/* no progress; do a Euclidean step */
5025
- if (l_divmod (a , b , NULL , & r ) < 0 )
5122
+ if (l_mod (a , b , & r ) < 0 )
5026
5123
goto error ;
5027
5124
Py_DECREF (a );
5028
5125
a = b ;
0 commit comments