在c++中使用pow()找到第n根的正确方法
Correct way to find nth root using pow() in c++
我必须求出最大等于10^18的数的n次方根,其中n等于10^4
我知道使用pow()我们可以用
x = (long int)(1e-7 + pow(number, 1.0 / n))
但这是给错误的答案在线编程法官,但在所有的情况下,我已经采取了,它是给出正确的结果。对于给定的约束,这种方法是否有问题
注:这里的n次方根是指其n次幂小于或等于给定数的最大整数,即x^n <= number的最大'x'。
根据答案,我知道这种方法是错误的,那么我应该怎么做呢?
你可以直接使用
x = (long int)pow(number, 1.0 / n)
考虑到n
的高值,大多数答案将是1。
在OP注释之后,这种方法确实是有缺陷的,因为在大多数情况下,1/n没有精确的浮点表示,并且1/n次幂的底数可以减去1。
而四舍五入不是较好的解决方法,它会使根多掉1。
另一个问题是10^18以内的值不能用双精度精确表示,而64位整型可以。
我的建议:
1)在(隐式)强制转换为double之前截断number的11位低位,以避免被FP单位舍入(不确定这是否有用)。
2)利用pow
函数得到n次根的劣估计,设r
。
3)仅使用整数运算(通过重复平方)计算r+1
的n次幂。
4)在n次幂合适的情况下,解是r+1
而不是r
。
在计算1/n时,FP单元仍有可能四舍五入,导致结果略大。我怀疑这个"太大"在最终结果中是否会像一个单位那么大,但这应该检查一下。
#include <cmath>
long find_nth_root(double X, int n)
{
long nth_root = std::trunc(std::pow(X, 1.0 / n));
// because of rounding error, it's possible that nth_root + 1 is what we actually want; let's check
if (std::pow(nth_root + 1, n) <= X) {
return nth_root + 1;
}
return nth_root;
}
当然,最初的问题是找到满足方程X≤yn 的最大整数Y。这很容易写:
long find_nth_root(double x, int d)
{
long i = 0;
for (; std::pow(i + 1, d) <= x; ++i) { }
return i;
}
这可能会运行得比你预期的要快。但是你可以用二进制搜索做得更好:
#include <cmath>
long find_nth_root(double x, int d)
{
long low = 0, high = 1;
while (std::pow(high, d) <= x) {
low = high;
high *= 2;
}
while (low != high - 1) {
long step = (high - low) / 2;
long candidate = low + step;
double value = std::pow(candidate, d);
if (value == x) {
return candidate;
}
if (value < x) {
low = candidate;
continue;
}
high = candidate;
}
return low;
}
我使用我编写的这个例程。这是我见过的最快的。它还可以处理最多64位。顺便说一下,n1是输入数。
for (n3 = 0; ((mnk) < n1) ; n3+=0.015625, nmrk++) {
mk += 0.0073125;
dad += 0.00390625;
mnk = pow(n1, 1.0/(mk+n3+dad));
mnk = pow(mnk, (mk+n3+dad));
}
虽然不总是完美的,但它确实是最接近的。
您可以尝试在C中使用unsigned获取nth_root:
// return a number that, when multiplied by itself nth times, makes N.
unsigned nth_root(const unsigned n, const unsigned nth) {
unsigned a = n, c, d, r = nth ? n + (n > 1) : n == 1 ;
for (; a < r; c = a + (nth - 1) * r, a = c / nth)
for (r = a, a = n, d = nth - 1; d && (a /= r); --d);
return r;
}
是它不包含<math.h>
,输出示例:
24 == (int) pow(15625, 1.0/3)
25 == nth_root(15625, 3)
0 == nth_root(0, 0)
1 == nth_root(1, 0)
4 == nth_root(4096, 6)
13 == nth_root(18446744073709551614, 17) // 64-bit 20 digits
11 == nth_root(340282366920938463463374607431768211454, 37) // 128-bit 39 digits
默认的猜测是变量a,设置为n
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- C++从另一个类访问公共静态向量的正确方法是什么
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 没有为自己的结构调用列表推回方法
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 枚举环境变量的惯用C++14/C++17方法
- 初始化具有非默认构造函数的std::数组项的更好方法