LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
nthroot_1.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
21static inline ulong pow_n(ulong x, ulong n) {
22 ulong ret = 1;
23 for (ulong i = 0; i < n; ++i) {
24 ret *= x;
25 }
26 return ret;
27}
28
29static const float inv_table[] = {
30 0.200000000000000, 0.166666666666667, 0.142857142857143, 0.125000000000000, 0.111111111111111, 0.100000000000000,
31 0.090909090909091, 0.083333333333333, 0.076923076923077, 0.071428571428571, 0.066666666666667, 0.062500000000000,
32 0.058823529411765, 0.055555555555556, 0.052631578947368, 0.050000000000000, 0.047619047619048, 0.045454545454545,
33 0.043478260869565, 0.041666666666667, 0.040000000000000, 0.038461538461538, 0.037037037037037, 0.035714285714286,
34 0.034482758620690, 0.033333333333333, 0.032258064516129, 0.031250000000000, 0.030303030303030, 0.029411764705882,
35 0.028571428571429, 0.027777777777778, 0.027027027027027, 0.026315789473684, 0.025641025641026, 0.025000000000000,
36};
37
38/* This table has the max possible base for a given root. For n >= 4,
39 max_base[n-4] = floor(UWORD_MAX^(1/n)).*/
40static const uint16_t max_base[] = {
41 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,
42 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};
43
45 ulong x, currval, base, upper_limit;
46
47 if (n == 0 || root == 0)
48 return 0;
49 if (root == 1)
50 return n;
51 if (root == 2)
52 return lmmp_sqrt_ulong_(n);
53 if (root == 3)
54 return lmmp_cbrt_ulong_(n);
55
56 if (root >= LIMB_BITS || n < (1ULL << root))
57 return 1;
58
59 /* n <= upper_limit^root */
60 upper_limit = max_base[root - 4];
61
62 if (upper_limit == 2)
63 return upper_limit;
64
65 /* upper_limit = 2 for root >= 41 */
66 lmmp_debug_assert(root <= 40);
67
68 if (root == 4)
69 x = sqrt(sqrt(n));
70 else
71 x = expf(inv_table[root - 5] * logf(n));
72
73 base = x;
74
75 if (base >= upper_limit)
76 base = upper_limit - 1;
77
78 currval = pow_n(base, root);
79 if (currval == n)
80 return base;
81
82 while (currval <= n) {
83 base++;
84 currval = pow_n(base, root);
85 if (base == upper_limit)
86 break;
87 }
88
89 while (currval > n) {
90 base--;
91 currval = pow_n(base, root);
92 }
93
94 return base;
95}
#define lmmp_debug_assert(x)
Definition lmmp.h:485
#define LIMB_BITS
Definition lmmp.h:123
#define n
static const float inv_table[]
Definition nthroot_1.c:29
static ulong pow_n(ulong x, ulong n)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition nthroot_1.c:21
static const uint16_t max_base[]
Definition nthroot_1.c:40
ulong lmmp_nthroot_ulong_(ulong n, ulong root)
计算 floor(n^(1/root))
Definition nthroot_1.c:44
ulong lmmp_cbrt_ulong_(ulong n)
计算算数立方根 floor(cbrt(n))
Definition cbrt_1.c:132
ulong lmmp_sqrt_ulong_(ulong a)
计算算术平方根 floor(sqrt(a))
Definition sqrt_1.c:22
uint64_t ulong
Definition numth.h:32