在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:58:58  来源:igfitidea点击:

finding cube root in C++?

c++math.hpow

提问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 of std::pow.

  • Cube-rooting 与将某物取 1/3 次幂是一样的,所以你可以做std::pow(x, 1/3.).

  • 在 C++11 中,您可以使用std::cbrt. C++11 引入了平方根和立方根函数,但没有克服std::pow.

回答by Cascabel

The power 1/3is 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/3as 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,但我的手册页在错误下说:

EDOMThe argument xis negative and yis 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 xto the 1/3power 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.

请注意,根据上下文,负数x1/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 doubleby 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 powfrom 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 cbrtfunction (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 的变量作为双...

回答by Luca Martini

I think you should not confuse exponentiation with the nth-root of a number. See the good old Wikipedia

我认为您不应该将幂运算与数字的 n 次方根混淆。请参阅古老的维基百科