1 #include "tommath_private.h"
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 /* SPDX-License-Identifier: Unlicense */
6 /* single digit division (based on routine from MPI) */
7 mp_err
mp_div_d(const mp_int
*a
, mp_digit b
, mp_int
*c
, mp_digit
*d
)
14 /* cannot divide by zero */
20 if ((b
== 1u) || mp_iszero(a
)) {
31 if (MP_HAS(MP_DIV_2
) && (b
== 2u)) {
33 *d
= mp_isodd(a
) ? 1u : 0u;
35 return (c
== NULL
) ? MP_OKAY
: mp_div_2(a
, c
);
37 if (MP_HAS(MP_DIV_2D
) && MP_IS_2EXPT(b
)) {
39 while ((ix
< MP_DIGIT_BIT
) && (b
!= (((mp_digit
)1)<<ix
))) {
43 *d
= a
->dp
[0] & (((mp_digit
)1<<(mp_digit
)ix
) - 1uL);
45 return (c
== NULL
) ? MP_OKAY
: mp_div_2d(a
, ix
, c
, NULL
);
49 if (MP_HAS(S_MP_DIV_3
) && (b
== 3u)) {
50 return s_mp_div_3(a
, c
, d
);
53 /* no easy answer [c'est la vie]. Just division */
54 if ((err
= mp_init_size(&q
, a
->used
)) != MP_OKAY
) {
61 for (ix
= a
->used
; ix
--> 0;) {
63 w
= (w
<< (mp_word
)MP_DIGIT_BIT
) | (mp_word
)a
->dp
[ix
];
65 t
= (mp_digit
)(w
/ b
);
66 w
-= (mp_word
)t
* (mp_word
)b
;