LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
tiny.c 文件参考
+ tiny.c 的引用(Include)关系图:

浏览源代码.

函数

int lmmp_leading_zeros_ (mp_limb_t x)
 计算一个单精度数(limb)中前导零的个数
 
int lmmp_limb_bits_ (mp_limb_t x)
 Copyright (C) 2026 HJimmyK(Jericho Knox)
 
int lmmp_limb_popcnt_ (mp_limb_t x)
 计算一个64位无符号整数中1的个数
 
mp_limb_t lmmp_mulh_ (mp_limb_t a, mp_limb_t b)
 计算两个64位无符号整数相乘的高位结果 (a*b)/B
 
void lmmp_mullh_ (mp_limb_t a, mp_limb_t b, mp_ptr restrict dst)
 
ulong lmmp_mulmod_ulong_ (ulong a, ulong b, ulong mod, ulongp restrict q)
 
int lmmp_tailing_zeros_ (mp_limb_t x)
 计算一个单精度数(limb)中末尾零的个数
 

函数说明

◆ lmmp_leading_zeros_()

int lmmp_leading_zeros_ ( mp_limb_t  x)

计算一个单精度数(limb)中前导零的个数

参数
x输入的64位无符号整数
返回
前导零的位数(范围:0~64)

在文件 tiny.c51 行定义.

51 {
52 if (x == 0) return 64;
53#ifdef __GNUC__
54 return __builtin_clzll(x);
55#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
56 unsigned long index;
57 _BitScanReverse64(&index, x);
58 return 63 - (int)index;
59#else
60 int n = 0;
61 if (x <= 0x00000000FFFFFFFF) { n += 32; x <<= 32; }
62 if (x <= 0x0000FFFFFFFFFFFF) { n += 16; x <<= 16; }
63 if (x <= 0x00FFFFFFFFFFFFFF) { n += 8; x <<= 8; }
64 if (x <= 0x0FFFFFFFFFFFFFFF) { n += 4; x <<= 4; }
65 if (x <= 0x3FFFFFFFFFFFFFFF) { n += 2; x <<= 2; }
66 if (x <= 0x7FFFFFFFFFFFFFFF) { n += 1; x <<= 1; }
67 return n;
68#endif
69}
#define n

引用了 n.

◆ lmmp_limb_bits_()

int lmmp_limb_bits_ ( mp_limb_t  x)

Copyright (C) 2026 HJimmyK(Jericho Knox)

计算满足 2^k > x 的最小自然数k

This file is part of LAMMP.

LAMMP is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed WITHOUT ANY WARRANTY.

See https://www.gnu.org/licenses/.

在文件 tiny.c21 行定义.

21 {
22 int k = 0;
23 while (x) {
24 x >>= 1;
25 k++;
26 }
27 return k;
28}
#define k

引用了 k , 以及 n.

◆ lmmp_limb_popcnt_()

int lmmp_limb_popcnt_ ( mp_limb_t  x)

计算一个64位无符号整数中1的个数

参数
x输入的64位无符号整数
返回
1的个数

在文件 tiny.c30 行定义.

30 {
31#if defined(__GNUC__) || defined(__clang__)
33#if defined(__x86_64__) && defined(USE_ASM)
34 __asm__ volatile("popcnt %1, %0" : "=r"(count) : "r"(x) : "cc");
35#else
37#endif
38 return count;
39#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
40 return (int)__popcnt64(x);
41#else
42 int k = 0;
43 while (x) {
44 k += x & 1;
45 x >>= 1;
46 }
47 return k;
48#endif
49}
uint64_t mp_limb_t
Definition lmmp.h:76

引用了 k , 以及 n.

◆ lmmp_mulh_()

mp_limb_t lmmp_mulh_ ( mp_limb_t  a,
mp_limb_t  b 
)

计算两个64位无符号整数相乘的高位结果 (a*b)/B

参数
a第一个64位无符号整数
b第二个64位无符号整数
返回
乘积的高64位结果

在文件 tiny.c91 行定义.

91 {
92#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
94 return (mp_limb_t)(t >> 64);
95#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
96 return __umulh(a, b);
97#else
98 uint64_t ah = a >> 32, bh = b >> 32;
99 a = (uint32_t)a, b = (uint32_t)b;
100 uint64_t r0 = a * b, r1 = a * bh, r2 = ah * b, r3 = ah * bh;
101 r3 += (r1 >> 32) + (r2 >> 32);
102 r1 = (uint32_t)r1, r2 = (uint32_t)r2;
103 r1 += r2;
104 r1 += (r0 >> 32);
105 return r3 + (r1 >> 32);
106#endif
107}
#define r2
#define r1
#define r3
#define r0
#define t

引用了 n, r0, r1, r2, r3 , 以及 t.

◆ lmmp_mullh_()

void lmmp_mullh_ ( mp_limb_t  a,
mp_limb_t  b,
mp_ptr restrict  dst 
)

在文件 tiny.c109 行定义.

109 {
110#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
112 dst[0] = (mp_limb_t)prod;
113 dst[1] = (mp_limb_t)(prod >> 64);
114#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
115 dst[0] = _umul128(a, b, dst + 1);
116#else
117 uint64_t ah = a >> 32, bh = b >> 32;
118 a = (uint32_t)a, b = (uint32_t)b;
119 uint64_t r0 = a * b, r1 = a * bh, r2 = ah * b, r3 = ah * bh;
120 r3 += (r1 >> 32) + (r2 >> 32);
121 r1 = (uint32_t)r1, r2 = (uint32_t)r2;
122 r1 += r2;
123 r1 += (r0 >> 32);
124 dst[1] = r3 + (r1 >> 32);
125 dst[0] = (r1 << 32) | (uint32_t)r0;
126#endif
127}

引用了 n, r0, r1, r2 , 以及 r3.

◆ lmmp_mulmod_ulong_()

ulong lmmp_mulmod_ulong_ ( ulong  a,
ulong  b,
ulong  mod,
ulongp restrict  q 
)

在文件 tiny.c129 行定义.

129 {
131 mod <<= shl;
133 ulong ab[2];
134 ulong r;
135 _umul64to128_(a, b, ab, ab + 1);
136 if (shl > 0)
137 _u128lshl(ab, ab, shl);
138 _udiv_qrnnd_preinv(*q, r, ab[1], ab[0], mod, inv);
139 return r >> shl;
140}
#define lmmp_leading_zeros_
Definition inlines.h:160
mp_limb_t lmmp_inv_1_(mp_limb_t x)
1阶逆元计算 (inv1)
Definition inv.c:117
static void _umul64to128_(uint64_t a, uint64_t b, uint64_t *low, uint64_t *high)
Definition longlong.h:174
#define _u128lshl(x, y, n)
Definition longlong.h:330
#define _udiv_qrnnd_preinv(q, r, nh, nl, d, di)
Definition longlong.h:415
uint64_t ulong
Definition numth.h:32

引用了 _u128lshl, _udiv_qrnnd_preinv, _umul64to128_(), lmmp_inv_1_(), lmmp_leading_zeros_ , 以及 n.

+ 函数调用图:

◆ lmmp_tailing_zeros_()

int lmmp_tailing_zeros_ ( mp_limb_t  x)

计算一个单精度数(limb)中末尾零的个数

参数
x输入的64位无符号整数
返回
末尾零的位数(范围:0~64)

在文件 tiny.c71 行定义.

71 {
72 if (x == 0) return 64;
73#ifdef __GNUC__
74 return __builtin_ctzll(x);
75#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64))
76 unsigned long index;
77 _BitScanForward64(&index, x);
78 return (int)index;
79#else
80 int n = 0;
81 if ((x & 0x00000000FFFFFFFF) == 0) { n += 32; x >>= 32; }
82 if ((x & 0x000000000000FFFF) == 0) { n += 16; x >>= 16; }
83 if ((x & 0x00000000000000FF) == 0) { n += 8; x >>= 8; }
84 if ((x & 0x000000000000000F) == 0) { n += 4; x >>= 4; }
85 if ((x & 0x0000000000000003) == 0) { n += 2; x >>= 2; }
86 if ((x & 0x0000000000000001) == 0) { n += 1; x >>= 1; }
87 return n;
88#endif
89}

引用了 n.