我怎样才能从 n 得到一个自次幂等于 n 的数?
How can I obtain from n a number which raised to the power of itself equals n?
我有一个整数n
,我想得到一个自次幂等于n
的数。我该怎么做?
TL;DR: 使用std::pow
.
您想求 n
的 1/n
次方。有一个标准函数可以找到 x
的 y
次方,称为 std::pow
。使用标准函数总是一个好主意,除非你有充分的理由不这样做。
所以,最好将这个问题改写为 "do you have any reasons to not use std::pow
?",而且,既然你在问社区,看起来你没有。
你的问题说明了两件事。
I want to get the n
th root of n
这意味着找到 x^n=n
的解决方案。为此 std::pow(n, 1./n)
将是一件好事。请注意,如果 n
是整数,1/n
可能会执行整数除法,因此您很可能会得到 std::pow(n, 0)
,即 1
。
I want to obtain a number which raised to the power of itself equals n
这是完全不同的东西。您正在尝试为 x
求解 x^x=n
。以n=2
和asking Wolfram Alpha about it为例,returns
x = exp(W(log(2)))
其中 W
将是 Lambert W function。据我所知,这不是 C++ 标准的一部分,因此您可能必须找到一个库(在源代码中或动态链接的)来为您计算该函数。 GSL 可能会服务。不过,推广到 n
的不同值应该是显而易见的。
所以我们要解方程x^x = n
。这与找到等同于 y^n = n
.
的 y = n-th n 的根完全不同
查看幂时首先要做的是考虑现在使用自然对数的对数,
x ln x = ln n
。这对我们没有太大帮助,也不是标准函数,因此需要某种形式的收敛例程,我们想解决 f(x) = x ln x - ln n = 0
。这个函数很好地单调增加,比 x 快一点,所以应该很容易解决。
我们可以使用Newton's method。先求导数
f'(x) = log x + 1
。从猜测 x1
开始,更新的猜测将是 x2 = x1 - f(x1) / f'(x)
。如果你这样做几次,它应该会很好地收敛。在我的实验中找到 x
这样 x^x = 21
它花了
不到 6 次迭代即可收敛。
伪代码
x[0] = ln(n);
for(i=0; i<6;++i ) {
fx = x[i] * ln( x[i] ) - ln(n);
df = ln( x[i] ) + 1;
x[i+1] = x[i] - fx / df;
}
println(x[6], pow(x[6], x[6]))
我有一个整数n
,我想得到一个自次幂等于n
的数。我该怎么做?
TL;DR: 使用std::pow
.
您想求 n
的 1/n
次方。有一个标准函数可以找到 x
的 y
次方,称为 std::pow
。使用标准函数总是一个好主意,除非你有充分的理由不这样做。
所以,最好将这个问题改写为 "do you have any reasons to not use std::pow
?",而且,既然你在问社区,看起来你没有。
你的问题说明了两件事。
I want to get the
n
th root ofn
这意味着找到 x^n=n
的解决方案。为此 std::pow(n, 1./n)
将是一件好事。请注意,如果 n
是整数,1/n
可能会执行整数除法,因此您很可能会得到 std::pow(n, 0)
,即 1
。
I want to obtain a number which raised to the power of itself equals
n
这是完全不同的东西。您正在尝试为 x
求解 x^x=n
。以n=2
和asking Wolfram Alpha about it为例,returns
x = exp(W(log(2)))
其中 W
将是 Lambert W function。据我所知,这不是 C++ 标准的一部分,因此您可能必须找到一个库(在源代码中或动态链接的)来为您计算该函数。 GSL 可能会服务。不过,推广到 n
的不同值应该是显而易见的。
所以我们要解方程x^x = n
。这与找到等同于 y^n = n
.
查看幂时首先要做的是考虑现在使用自然对数的对数,
x ln x = ln n
。这对我们没有太大帮助,也不是标准函数,因此需要某种形式的收敛例程,我们想解决 f(x) = x ln x - ln n = 0
。这个函数很好地单调增加,比 x 快一点,所以应该很容易解决。
我们可以使用Newton's method。先求导数
f'(x) = log x + 1
。从猜测 x1
开始,更新的猜测将是 x2 = x1 - f(x1) / f'(x)
。如果你这样做几次,它应该会很好地收敛。在我的实验中找到 x
这样 x^x = 21
它花了
不到 6 次迭代即可收敛。
伪代码
x[0] = ln(n);
for(i=0; i<6;++i ) {
fx = x[i] * ln( x[i] ) - ln(n);
df = ln( x[i] ) + 1;
x[i+1] = x[i] - fx / df;
}
println(x[6], pow(x[6], x[6]))