简体   繁体   中英

Division using GMP's low-level API

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM