finding cube root in C++?

2019-02-09 00:33发布

Strange things happen when i try to find the cube root of a number.

The following code returns me undefined. In 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

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?

标签: c++ math.h pow
12条回答
forever°为你锁心
2楼-- · 2019-02-09 00:52

I was looking for cubit root and found this thread and it occurs to me that the following code might work:

#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;
}
查看更多
地球回转人心会变
3楼-- · 2019-02-09 00:56

C++11 has the cbrt function (see for example http://en.cppreference.com/w/cpp/numeric/math/cbrt) so you can write something like

#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/bFlXYs seems 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

查看更多
Melony?
4楼-- · 2019-02-09 00:59

Don't cast to double by using (double), use a double numeric constant instead:

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.

Alternatively, use pow from the <complex> header for the reasons stated by buddhabrot

查看更多
走好不送
5楼-- · 2019-02-09 01:01

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...

查看更多
smile是对你的礼貌
6楼-- · 2019-02-09 01:04

If you ever have no math library you can use this way to compute the cubic root:

cubic root

double curt(double x) {
  if (x == 0) {
    // would otherwise return something like 4.257959840008151e-109
    return 0;
  }
  double b = 1; // use any value except 0
  double last_b_1 = 0;
  double last_b_2 = 0;
  while (last_b_1 != b && last_b_2 != b) {
    last_b_1 = b;
    // use (2 * b + x / b / b) / 3 for small numbers, as suggested by  willywonka_dailyblah
    b = (b + x / b / b) / 2;
    last_b_2 = b;
    // use (2 * b + x / b / b) / 3 for small numbers, as suggested by  willywonka_dailyblah
    b = (b + x / b / b) / 2;
  }
  return b;
}

It is derives from the sqrt algorithm below. The idea is that b and x / b / b bigger and smaller from the cubic root of x. So, the average of both lies closer to the cubic root of x.

Square Root And Cubic Root (in Python)

def sqrt_2(a):
    if a == 0:
        return 0
    b = 1
    last_b = 0
    while last_b != b:
        last_b = b
        b = (b + a / b) / 2
    return b

def curt_2(a):
    if a == 0:
        return 0
    b = a
    last_b_1 = 0;
    last_b_2 = 0;
    while (last_b_1 != b and last_b_2 != b):
        last_b_1 = b;
        b = (b + a / b / b) / 2;
        last_b_2 = b;
        b = (b + a / b / b) / 2;
    return b

In contrast to the square root, last_b_1 and last_b_2 are required in the cubic root because b flickers. You can modify these algorithms to compute the fourth root, fifth root and so on.

Thanks to my math teacher Herr Brenner in 11th grade who told me this algorithm for sqrt.

Performance

I tested it on an Arduino with 16mhz clock frequency:

查看更多
ら.Afraid
7楼-- · 2019-02-09 01:13

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);
}
查看更多
登录 后发表回答