LAMMP
4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
nthroot.c
浏览该文件的文档.
1
/**
2
* Copyright (C) 2026 HJimmyK(Jericho Knox)
3
*
4
* This file is part of LAMMP.
5
*
6
* LAMMP is free software: you can redistribute it and/or modify it under
7
* the terms of the GNU Lesser General Public License (LGPL) as published
8
* by the Free Software Foundation; either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed WITHOUT ANY WARRANTY.
12
*
13
* See <https://www.gnu.org/licenses/>.
14
*/
15
16
#include <math.h>
17
18
#include "../../../include/lammp/numth.h"
19
20
21
ulong
lmmp_sqrt_ulong_
(
ulong
a
) {
22
ulong
is
;
23
24
is
= (
ulong
)
sqrt
((
double
)
a
);
25
26
is
-= (
is
*
is
>
a
);
27
if
(
is
== (1ULL << 32))
28
is
--;
29
return
is
;
30
}
31
32
static
inline
ulong
pow_n
(
ulong
x
,
ulong
n
) {
33
ulong
ret
= 1;
34
for
(
ulong
i
= 0;
i
<
n
; ++
i
) {
35
ret
*=
x
;
36
}
37
return
ret
;
38
}
39
40
static
const
float
inv_table
[] = {
41
0.200000000000000, 0.166666666666667, 0.142857142857143, 0.125000000000000, 0.111111111111111, 0.100000000000000,
42
0.090909090909091, 0.083333333333333, 0.076923076923077, 0.071428571428571, 0.066666666666667, 0.062500000000000,
43
0.058823529411765, 0.055555555555556, 0.052631578947368, 0.050000000000000, 0.047619047619048, 0.045454545454545,
44
0.043478260869565, 0.041666666666667, 0.040000000000000, 0.038461538461538, 0.037037037037037, 0.035714285714286,
45
0.034482758620690, 0.033333333333333, 0.032258064516129, 0.031250000000000, 0.030303030303030, 0.029411764705882,
46
0.028571428571429, 0.027777777777778, 0.027027027027027, 0.026315789473684, 0.025641025641026, 0.025000000000000,
47
};
48
49
/* This table has the max possible base for a given root. For n >= 4,
50
max_base[n-4] = floor(UWORD_MAX^(1/n)).*/
51
static
const
uint16_t
max_base
[] = {
52
65535, 7131, 1625, 565, 255, 138, 84, 56, 40, 30, 23, 19, 15, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3,
53
3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
54
55
ulong
lmmp_nthroot_ulong_
(
ulong
n
,
ulong
root) {
56
ulong
x
,
currval
, base,
upper_limit
;
57
58
if
(
n
== 0 || root == 0)
59
return
0;
60
if
(root == 1)
61
return
n
;
62
if
(root == 2)
63
return
lmmp_sqrt_ulong_
(
n
);
64
if
(root == 3)
65
return
lmmp_cbrt_ulong_
(
n
);
66
67
if
(root >=
LIMB_BITS
||
n
< (1ULL << root))
68
return
1;
69
70
/* n <= upper_limit^root */
71
upper_limit
=
max_base
[root - 4];
72
73
if
(
upper_limit
== 2)
74
return
upper_limit
;
75
76
/* upper_limit = 2 for root >= 41 */
77
lmmp_debug_assert
(root <= 40);
78
79
if
(root == 4)
80
x
=
sqrt
(
sqrt
(
n
));
81
else
82
x
=
expf
(
inv_table
[root - 5] *
logf
(
n
));
83
84
base =
x
;
85
86
if
(base >=
upper_limit
)
87
base =
upper_limit
- 1;
88
89
currval
=
pow_n
(base, root);
90
if
(
currval
==
n
)
91
return
base;
92
93
while
(
currval
<=
n
) {
94
base++;
95
currval
=
pow_n
(base, root);
96
if
(base ==
upper_limit
)
97
break
;
98
}
99
100
while
(
currval
>
n
) {
101
base--;
102
currval
=
pow_n
(base, root);
103
}
104
105
return
base;
106
}
lmmp_debug_assert
#define lmmp_debug_assert(x)
Definition
lmmp.h:390
LIMB_BITS
#define LIMB_BITS
Definition
lmmp.h:86
n
#define n
inv_table
static const float inv_table[]
Definition
nthroot.c:40
pow_n
static ulong pow_n(ulong x, ulong n)
Definition
nthroot.c:32
lmmp_sqrt_ulong_
ulong lmmp_sqrt_ulong_(ulong a)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition
nthroot.c:21
max_base
static const uint16_t max_base[]
Definition
nthroot.c:51
lmmp_nthroot_ulong_
ulong lmmp_nthroot_ulong_(ulong n, ulong root)
计算 floor(n^(1/root))
Definition
nthroot.c:55
lmmp_cbrt_ulong_
ulong lmmp_cbrt_ulong_(ulong n)
计算算数立方根 floor(cbrt(n))
Definition
cbrt_1.c:133
ulong
uint64_t ulong
Definition
numth.h:32
src
lammp
numth
nthroot.c
生成于 2026年 七月 12日 星期日 16:40:19 , 为 LAMMP使用
1.9.8