c++mathcmath

Getting NaN value when raising double by a fractional exponent of 1/3


I'm new to C++ so if there is a quick solution to this question please let me know in the comments.

I'm working on a third-degree polynomial equation solver application, and for that I need to divide a certain double value by a fractional exponent, which in this case is 1/3.

Here is the code so far:

#include <iostream>
#include <valarray>
#include <vector>
#include <iomanip>

using namespace std;

void solveEquation(double a, double b, double c, double d);

int main() {
    double a, b, c, d;


    cout << "Input a value for 'a': " << endl;
    cin >> a;

    cout << "Input a value for 'b': " << endl;
    cin >> b;

    cout << "Input a value for 'c': " << endl;
    cin >> c;

    cout << "Input a value for 'd': " << endl;
    cin >> d;

    solveEquation(a, b, c, d);
    return 0;
}

void solveEquation(double a, double b, double c, double d) {
    vector<double> frac_vector1{((pow(-b, 3)) / (27 * pow(a, 3))),
                               ((b * c) / (6 * pow(a, 2))),
                               -(d / (2 * a))};
    double frac_vector1_result = 0;
    for (double frac : frac_vector1) {
        frac_vector1_result += frac;
    }

    double frac_vector1_result_pow = pow(frac_vector1_result, 2);

    vector<double> frac_vector2 {(c/(3 * a)),
                                 -((pow(b, 2))/(9 * pow(2, a)))};

    double frac_vector2_result = 0;
    for (double frac : frac_vector2) {
        frac_vector2_result += frac;
    }

    double frac_vector2_result_pow3 = pow(frac_vector2_result, 3);

    double first_half = (frac_vector1_result + sqrt(frac_vector1_result_pow + frac_vector2_result_pow3));

    cout << pow(first_half, 1.0/3.0); //isNan ?
}

When I input a = -0.71, b = -0.3, c = 2.2, and d = -1.46 I get a NaN value, which is not what I get in a calculator.

When I debug this I get the following value for first_half:

enter image description here

When I raise this value to 1/3 in Desmos I get -0.853432944643.

It's not like I am square rooting a negative number (it's 1/3 not 1/2) so why am I getting this problem?

Cheers,

Tom


Solution

  • pow does not support taking roots of negative number in this fashion.

    cppreference on std::pow:

    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.

    C++ provides a function for directly computing the cube root, std::cbrt:

    std::cbrt(first_half);
    

    This means you don't need to worry about what sign first_half ends up being to avoid domain errors.