longlong.h – support functions for multi-word arithmetic¶
Auxiliary asm macros¶
-
umul_ppmm(high_prod, low_prod, multiplier, multiplicand)¶
Multiplies two single limb integers
MULTIPLIER
andMULTIPLICAND
, and generates a two limb product inHIGH_PROD
andLOW_PROD
.
-
smul_ppmm(high_prod, low_prod, multiplier, multiplicand)¶
As for
umul_ppmm()
but the numbers are signed.
-
udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator)¶
Divides an unsigned integer, composed by the limb integers
HIGH_NUMERATOR
andLOW_NUMERATOR
, byDENOMINATOR
and places the quotient inQUOTIENT
and the remainder inREMAINDER
.HIGH_NUMERATOR
must be less thanDENOMINATOR
for correct operation.
-
sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator)¶
As for
udiv_qrnnd()
but the numbers are signed. The quotient is rounded towards \(0\). Note that as the quotient is signed it must lie in the range \([-2^63, 2^63)\).
-
flint_clz(x)¶
Returns the number of zero-bits from the msb to the first non-zero bit in the limb
x
. This is the number of stepsx
needs to be shifted left to set the msb. Ifx
is \(0\) then the return value is undefined.
-
flint_ctz(x)¶
As for
flint_clz()
, but counts from the least significant end. Ifx
is zero then the return value is undefined.
-
add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, high_addend_2, low_addend_2)¶
Adds two limb integers, composed by
HIGH_ADDEND_1
andLOW_ADDEND_1
, andHIGH_ADDEND_2
andLOW_ADDEND_2
, respectively. The result is placed inHIGH_SUM
andLOW_SUM
. Overflow, i.e. carry out, is not stored anywhere, and is lost.
-
add_sssaaaaaa(high_sum, mid_sum, low_sum, high_addend_1, mid_addend_1, low_addend_1, high_addend_2, mid_addend_2, low_addend_2)¶
Adds two three limb integers. Carry out is lost.
-
sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, high_subtrahend, low_subtrahend)¶
Subtracts two limb integers, composed by
HIGH_MINUEND_1
andLOW_MINUEND_1
, andHIGH_SUBTRAHEND_2
andLOW_SUBTRAHEND_2
, respectively. The result is placed inHIGH_DIFFERENCE
andLOW_DIFFERENCE
. Overflow, i.e. carry out is not stored anywhere, and is lost.
-
sub_dddmmmsss(high_diff, mid_diff, low_diff, high_minuend_1, mid_minuend_1, low_minuend_1, high_subtrahend_2, mid_subtrahend_2, low_subtrahend_2)¶
Subtracts two three limb integers. Borrow out is lost.
-
byte_swap(x)¶
Swap the order of the bytes in the word \(x\), i.e. most significant byte becomes least significant byte, etc.
-
invert_limb(invxl, xl)¶
Deprecated: see
n_preinvert_limb_prenorm()
.
-
udiv_qrnnd_preinv(q, r, nh, nl, d, di)¶
As for
udiv_qrnnd()
but takes a precomputed inversedi
as computed byinvert_limb()
. The algorithm, in terms of the theorem above, is:nadj = n1*(d-B/2) + n0 xh, xl = (n2+n1)*(m-B) xh, xl += nadj + n2*B ( xh, xl = n2*B + (n2+n1)*(m-B) + n1*(d-B/2) + n0 ) _q1 = B - xh - 1 xh, xl = _q1*d + nh, nl - B*d = nh, nl - q1*d - d so that xh = 0 or -1 r = xl + xh*d where xh is 0 if q1 is off by 1, otherwise -1 q = xh - _q1 = xh + 1 + n2