7#include "../../../include/lammp/lmmpn.h"
8#include "../../../include/lammp/numth.h"
9#include "../../../include/lammp/impl/longlong.h"
22 return __builtin_popcountll(x);
24 return (
int)__popcnt64(x);
36 if (x == 0)
return 64;
38 return __builtin_clzll(x);
41 _BitScanReverse64(&index, x);
42 return 63 - (int)index;
45 if (x <= 0x00000000FFFFFFFF) { n += 32; x <<= 32; }
46 if (x <= 0x0000FFFFFFFFFFFF) { n += 16; x <<= 16; }
47 if (x <= 0x00FFFFFFFFFFFFFF) { n += 8; x <<= 8; }
48 if (x <= 0x0FFFFFFFFFFFFFFF) { n += 4; x <<= 4; }
49 if (x <= 0x3FFFFFFFFFFFFFFF) { n += 2; x <<= 2; }
50 if (x <= 0x7FFFFFFFFFFFFFFF) { n += 1; x <<= 1; }
55 if (x == 0)
return 64;
57 return __builtin_ctzll(x);
60 _BitScanForward64(&index, x);
64 if ((x & 0x00000000FFFFFFFF) == 0) { n += 32; x >>= 32; }
65 if ((x & 0x000000000000FFFF) == 0) { n += 16; x >>= 16; }
66 if ((x & 0x00000000000000FF) == 0) { n += 8; x >>= 8; }
67 if ((x & 0x000000000000000F) == 0) { n += 4; x >>= 4; }
68 if ((x & 0x0000000000000003) == 0) { n += 2; x >>= 2; }
69 if ((x & 0x0000000000000001) == 0) { n += 1; x >>= 1; }
74#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
75 __uint128_t t = (__uint128_t)a * (__uint128_t)b;
77#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
80 uint64_t ah = a >> 32, bh = b >> 32;
81 a = (uint32_t)a, b = (uint32_t)b;
82 uint64_t
r0 = a * b,
r1 = a * bh,
r2 = ah * b,
r3 = ah * bh;
83 r3 += (
r1 >> 32) + (
r2 >> 32);
84 r1 = (uint32_t)
r1,
r2 = (uint32_t)
r2;
87 return r3 + (
r1 >> 32);
92#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
93 __uint128_t prod = (__uint128_t)a * b;
96#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
97 dst[0] = _umul128(a, b, dst + 1);
99 uint64_t ah = a >> 32, bh = b >> 32;
100 a = (uint32_t)a, b = (uint32_t)b;
101 uint64_t
r0 = a * b,
r1 = a * bh,
r2 = ah * b,
r3 = ah * bh;
102 r3 += (
r1 >> 32) + (
r2 >> 32);
103 r1 = (uint32_t)
r1,
r2 = (uint32_t)
r2;
106 dst[1] =
r3 + (
r1 >> 32);
107 dst[0] = (
r1 << 32) | (uint32_t)
r0;
mp_limb_t lmmp_inv_1_(mp_limb_t x)
1阶逆元计算 (inv1)
static void _umul64to128_(uint64_t a, uint64_t b, uint64_t *low, uint64_t *high)
#define _u128lshl(x, y, n)
#define _udiv_qrnnd_preinv(q, r, nh, nl, d, di)
int lmmp_leading_zeros_(mp_limb_t x)
计算一个单精度数(limb)中前导零的个数
int lmmp_tailing_zeros_(mp_limb_t x)
计算一个单精度数(limb)中末尾零的个数
void lmmp_mullh_(mp_limb_t a, mp_limb_t b, mp_ptr restrict dst)
mp_limb_t lmmp_mulh_(mp_limb_t a, mp_limb_t b)
计算两个64位无符号整数相乘的高位结果 (a*b)/2^64
int lmmp_limb_bits_(mp_limb_t x)
计算满足 2^k > x 的最小自然数k
int lmmp_limb_popcnt_(mp_limb_t x)
计算一个64位无符号整数中1的个数
ulong lmmp_mulmod_ulong_(ulong a, ulong b, ulong mod, ulongp restrict q)