简体   繁体   中英

Why does this cout << pow(-3, (1.0 / 3)) return -nan(ind)?

Why does this:

cout << pow(-3, (1.0 / 3))

return

-nan(ind)

whereas

pow(-3, 3)

and

pow(3, (1.0 / 3))

both work fine ?

The pow function is used only for positive numbers.

See the man page of pow function :

If x is a finite value less than 0, and y is a finite noninteger, a domain error occurs, and a NaN is returned.

To get the power of number you can try like this:

int main() {
    int exp;
    float base, power = 1;

    cout << "Base and exponent :  ";
    cin >> base >> exp;

    while (exp != 0) {
        power *= base;
        --exp;
    }

    cout << "Output = " << power;

    return 0;
}

pow(x, y) for floating point types is probably implemented as exp(y * ln(x)) .

ln(x) fails for negative numbers, or zero.

For a full reference, see http://en.cppreference.com/w/cpp/numeric/math/pow

This is because mathematically the fractional power of a negative number delivers a complex number.

Reference for std::pow states that " pow(base, exp) returns NaN and raises FE_INVALID if base is finite and negative and exp is finite and non-integer."

This is plain mathemetics:

  • pow(-3, 3) ==> (-3) 3
  • pow(3, (1.0 / 3) ==> 3 1/3 = 3 √3
  • pow(-3, (1.0 / 3) ==> (-3) 1/3 = 3 √(-3) ==> Not possible, you cannot take the root of a negative number. It is imaginary.

You can find the list of special case on the cppreference.com pow page:

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.

If the implementation supports IEEE floating-point arithmetic (IEC 60559),

  • pow(+0, exp) , where exp is a negative odd integer, returns +∞ and raises FE_DIVBYZERO
  • pow(-0, exp) , where exp is a negative odd integer, returns -∞ and raises FE_DIVBYZERO
  • pow(±0, exp) , where exp is negative, finite, and is an even integer or a non-integer, - returns +∞ and raises FE_DIVBYZERO
  • pow(±0, -∞) returns +∞ and may raise FE_DIVBYZERO
  • pow(+0, exp) , where exp is a positive odd integer, returns +0
  • pow(-0, exp) , where exp is a positive odd integer, returns -0
  • pow(±0, exp) , where exp is positive non-integer or a positive even integer, returns +0
  • pow(-1, ±∞) returns 1
  • pow(+1, exp) returns 1 for any exp, even when exp is NaN
  • pow(base, ±0) returns 1 for any base, even when base is NaN
  • pow(base, exp) returns NaN and raises FE_INVALID if base is finite and negative and exp is finite and non-integer.
  • pow(base, -∞) returns +∞ for any |base|<1
  • pow(base, -∞) returns +0 for any |base|>1
  • pow(base, +∞) returns +0 for any |base|<1
  • pow(base, +∞) returns +∞ for any |base|>1
  • pow(-∞, exp) returns -0 if exp is a negative odd integer
  • pow(-∞, exp) returns +0 if exp is a negative non-integer or even integer
  • pow(-∞, exp) returns -∞ if exp is a positive odd integer
  • pow(-∞, exp) returns +∞ if exp is a positive non-integer or even integer
  • pow(+∞, exp) returns +0 for any negative exp
  • pow(+∞, exp) returns +∞ for any positive exp except where specified above, if any argument is NaN, NaN is returned

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM