在 C++ 中找到立方根?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4269069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
finding cube root in C++?
提问by ilcredo
Strange things happen when i try to find the cube root of a number.
当我试图找到一个数字的立方根时,会发生奇怪的事情。
The following code returns me undefined. In cmd : -1.#IND
以下代码返回我未定义。在 cmd 中:-1.#IND
cout<<pow(( double )(20.0*(-3.2) + 30.0),( double )1/3)
While this one works perfectly fine. In cmd : 4.93242414866094
虽然这个工作得很好。在 cmd 中:4.93242414866094
cout<<pow(( double )(20.0*4.5 + 30.0),( double )1/3)
From mathematical way it must work since we can have the cube root from a negative number. Pow is from Visual C++ 2010 math.h library. Any ideas?
从数学方式来看,它必须起作用,因为我们可以从负数得到立方根。Pow 来自 Visual C++ 2010 math.h 库。有任何想法吗?
回答by wkl
pow(x, y)
from <cmath>
does NOT work if x is negative and y is non-integral.
pow(x, y)
<cmath>
如果 x 为负且 y 为非整数,则from不起作用。
This is a limitation of std::pow
, as documented in the C standard and on cppreference:
这是 的限制std::pow
,如 C 标准和cppreference 中所述:
Error handling
- Errors are reported as specified in math_errhandling
- If base is finite and negative and exp is finite and non-integer, a domain error occurs and a range error may occur.
- If base is zero and exp is zero, a domain error may occur.
- If base is zero and exp is negative, a domain error or a pole error may occur.
错误处理
- 按照 math_errhandling 中指定的方式报告错误
- 如果 base 有限且为负,exp 有限且非整数,则会出现域错误并可能出现范围错误。
- 如果 base 为零且 exp 为零,则可能会出现域错误。
- 如果 base 为零且 exp 为负,则可能会出现域错误或极点错误。
There are a couple ways around this limitation:
有几种方法可以解决此限制:
Cube-rooting is the same as taking something to the 1/3 power, so you could do
std::pow(x, 1/3.)
.In C++11, you can use
std::cbrt
. C++11 introduced both square-root and cube-root functions, but no generic n-th root function that overcomes the limitations ofstd::pow
.
Cube-rooting 与将某物取 1/3 次幂是一样的,所以你可以做
std::pow(x, 1/3.)
.在 C++11 中,您可以使用
std::cbrt
. C++11 引入了平方根和立方根函数,但没有克服std::pow
.
回答by Cascabel
The power 1/3
is a special case. In general, non-integral powers of negative numbers are complex. It wouldn't be practical for pow to check for special cases like integer roots, and besides, 1/3
as a double is not exactly 1/3!
权力1/3
是一个特例。一般来说,负数的非整数幂是复数。pow 检查整数根之类的特殊情况是不切实际的,此外,1/3
因为 double 不完全是 1/3!
I don't know about the visual C++ pow, but my man page says under errors:
我不知道 Visual C++ pow,但我的手册页在错误下说:
EDOM
The argumentx
is negative andy
is not an integral value. This would result in a complex number.
EDOM
参数x
为负且y
不是整数值。这将导致一个复数。
You'll have to use a more specialized cube root function if you want cube roots of negative numbers - or cut corners and take absolute value, then take cube root, then multiply the sign back on.
如果您想要负数的立方根,则必须使用更专业的立方根函数 - 或者切角并取绝对值,然后取立方根,然后再乘以符号。
Note that depending on context, a negative number x
to the 1/3
power is not necessarily the negative cube root you're expecting. It could just as easily be the first complex root, x^(1/3) * e^(pi*i/3)
. This is the convention mathematica uses; it's also reasonable to just say it's undefined.
请注意,根据上下文,负数x
的1/3
力量不是你期望的负立方根。它可以很容易地成为第一个复杂的根,x^(1/3) * e^(pi*i/3)
. 这是 mathematica 使用的约定;说它未定义也是合理的。
回答by buddhabrot
While (-1)^3 = -1, you can't simply take a rational power of a negative number and expect a real response. This is because there are other solutions to this rational exponent that are imaginary in nature.
http://www.wolframalpha.com/input/?i=x^(1/3),+x+from+-5+to+0
当 (-1)^3 = -1 时,您不能简单地取负数的有理数幂并期望得到真实响应。这是因为对于这个有理指数还有其他的解,它们本质上是虚的。
http://www.wolframalpha.com/input/?i=x^(1/3),+x+from+-5+to+0
Similarily, plot x^x. For x = -1/3, this should have a solution. However, this function is deemed undefined in R for x < 0.
同样,绘制 x^x。对于 x = -1/3,这应该有一个解决方案。但是,对于 x < 0,该函数在 R 中被视为未定义。
Therefore, don't expect math.h to do magic that would make it inefficient, just change the signs yourself.
因此,不要指望 math.h 会做会使其效率低下的魔术,只需自己更改符号即可。
回答by jon_darkstar
Guess you gotta take the negative out and put it in afterwards. You can have a wrapper do this for you if you really want to.
猜猜你得把底片拿出来然后再放进去。如果你真的想要,你可以让一个包装器为你做这件事。
function yourPow(double x, double y)
{
if (x < 0)
return -1.0 * pow(-1.0*x, y);
else
return pow(x, y);
}
回答by rubenvb
Don't cast to double
by using (double)
, use a double numeric constant instead:
不要double
通过 using强制转换为(double)
,而是使用双数值常量:
double thingToCubeRoot = -20.*3.2+30;
cout<< thingToCubeRoot/fabs(thingToCubeRoot) * pow( fabs(thingToCubeRoot), 1./3. );
Should do the trick!
应该做的伎俩!
Also: don't include <math.h>
in C++ projects, but use <cmath>
instead.
另外:不要包含<math.h>
在 C++ 项目中,而是使用<cmath>
。
Alternatively, use pow
from the <complex>
header for the reasons stated by buddhabrot
或者,出于 buddhabrot 所述的原因,pow
从<complex>
标题中使用
回答by CashCow
pow( x, y )
is the same as (i.e. equivalent to) exp( y * log( x ) )
pow( x, y )
与(即等同于)相同 exp( y * log( x ) )
if log(x) is invalid then pow(x,y) is also.
如果 log(x) 无效,则 pow(x,y) 也是无效的。
Similarly you cannot perform 0 to the power of anything, although mathematically it should be 0.
同样,您不能执行 0 的任何次幂,尽管从数学上讲它应该是 0。
回答by Alessandro Jacopson
C++11 has the cbrt
function (see for example http://en.cppreference.com/w/cpp/numeric/math/cbrt) so you can write something like
C++11 具有该cbrt
功能(例如参见http://en.cppreference.com/w/cpp/numeric/math/cbrt),因此您可以编写类似
#include <iostream>
#include <cmath>
int main(int argc, char* argv[])
{
const double arg = 20.0*(-3.2) + 30.0;
std::cout << cbrt(arg) << "\n";
std::cout << cbrt(-arg) << "\n";
return 0;
}
I do not have access to the C++ standard so I do not know how the negative argument is handled... a test on ideone http://ideone.com/bFlXYsseems to confirm that C++ (gcc-4.8.1) extends the cube root with this rule cbrt(x)=-cbrt(-x)
when x<0
; for this extension you can see http://mathworld.wolfram.com/CubeRoot.html
我无权访问 C++ 标准,所以我不知道如何处理否定参数......对 ideone http://ideone.com/bFlXYs的测试似乎证实 C++ (gcc-4.8.1) 扩展了立方根与此规则cbrt(x)=-cbrt(-x)
时x<0
;对于这个扩展,你可以看到http://mathworld.wolfram.com/CubeRoot.html
回答by guinny
I was looking for cubit root and found this thread and it occurs to me that the following code might work:
我正在寻找 cubit root 并找到了这个线程,我发现以下代码可能有效:
#include <cmath>
using namespace std;
function double nth-root(double x, double n){
if (!(n%2) || x<0){
throw FAILEXCEPTION(); // even root from negative is fail
}
bool sign = (x >= 0);
x = exp(log(abs(x))/n);
return sign ? x : -x;
}
回答by karan
because the 1/3 will always return 0 as it will be considered as integer... try with 1.0/3.0... it is what i think but try and implement... and do not forget to declare variables containing 1.0 and 3.0 as double...
因为 1/3 将始终返回 0,因为它将被视为整数...尝试使用 1.0/3.0...这是我的想法,但尝试实现...并且不要忘记声明包含 1.0 和 3.0 的变量作为双...