I'm using GMP's low-level interface ( mpn_
, see https://gmplib.org/manual/Low_002dlevel-Functions ) to do some fixed-size 192 bit (three limb) integer calculations.
Currently I am trying to divide one random uint192 by another random uint192 and fail to select the right function. There are multiple candidates:
mpn_tdiv_qr
- Documentation says "most significant limb of the divisor must be non-zero" mpn_divrem
- Documentation says "obsolete" mpn_divrem_1
- Takes a single limb as a divisor mpn_divexact_1
- Documentation says "expecting... to divide exactly" So there is an obsolete function ( mpn_divrem
), a function that takes small (<= 64bit) divisors only ( mpn_divrem_1
), one that has undefined behavior with remainders ( mpn_divexact_1
) and one that takes large (>= 129bit) divisors only ( mpn_tdiv_qr
).
I tried mpn_tdiv_qr
since I thought I'm misunderstanding the documentation and because it replaces the obsolete function. But it actually crashes when most significant limb is zero.
Did I miss something? How can I divide two random 3-limb-numbers? Or numbers with a divisor of 65..128 non-zero bits (eg 0xffffffff'ffffffffffffffff'ffffffffffffffff / 0xff'ffffffffffffffff
)?
Ok, solution is simple: Instead of passing the number of allocated limbs to mpn_tdiv_qr
pass the number of limbs minus the number of leading zero limbs of the divisor instead. Eg when using 3 limbs and a concrete divisor has limb[2] == 0
, limb[1] != 0
and limb[0] == 0
a 2
is passed for the divisor length. This way it is guaranteed that the most significant limb (in this case [1]
) is non-zero.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.