【问题标题】:Why does this cout << pow(-3, (1.0 / 3)) return -nan(ind)?为什么这个 cout << pow(-3, (1.0 / 3)) 返回 -nan(ind)?
【发布时间】:2015-11-12 10:10:16
【问题描述】:

为什么会这样:

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

返回

-nan(ind)

pow(-3, 3)

pow(3, (1.0 / 3))

两者都工作正常?

【问题讨论】:

    标签: c++ pow


    【解决方案1】:

    这是因为从数学上讲,负数的小数幂会产生一个复数。

    Reference for std::pow 声明“pow(base, exp) 返回 NaN 并在 base 为有限且为负且 exp 为有限且非整数时引发 FE_INVALID。”

    【讨论】:

    • 嗯,在数学上你肯定可以:但答案并不真实。
    • 是的,抱歉,如果您允许使用复数,则可以
    • 如果你改写那个数学教条,这将是一个很好的答案。
    【解决方案2】:

    浮点类型的pow(x, y) 可能实现为exp(y * ln(x))

    ln(x) 因负数或零而失败。

    如需完整参考,请参阅http://en.cppreference.com/w/cpp/numeric/math/pow

    【讨论】:

      【解决方案3】:

      pow 函数仅用于正数。

      查看pow function的手册页:

      如果 x 是小于 0 的有限值,并且 y 是有限非整数,则 a 发生域错误,并返回一个 NaN。

      要获得数字的力量,你可以这样尝试:

      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;
      }
      

      【讨论】:

      • soo,当 x
      • @MaverickS:- 更新了我的答案。请检查!
      【解决方案4】:

      这是简单的数学:

      • pow(-3, 3) ==> (-3)3
      • pow(3, (1.0 / 3) ==> 31/3 = 3√3
      • pow(-3, (1.0 / 3) ==> (-3)1/3 = 3√(-3) ==> 不可能,你不能取负数的根。它是虚数。

      【讨论】:

      • 不过还是可以的。只是pow(double, double) 不支持。而且您的第二个陈述不正确,有三个立方根:您只选择了实线中的那个。
      • 如何在现实世界中求一个负数的根?答案是虚数 = √3 * i。我的第二个陈述中有什么不正确的地方?
      • @Bathsheba,将数学视为不包括虚数是完全正确的。数学不是一个具有内在规律的普遍系统。它是各种系统,每个系统都有决定(而不是固有的)规则。当使用双打进行计算机编程时,没有虚数的数学系统很可能是预期的。它们被称为“虚构的”是有原因的。
      • 确实如此,尽管我发现“普通数学”教条且不精确。
      • 你能解释一下什么是不精确的吗?我无法想象一种语言会为负平方根产生浮点或双精度结果。因为它会违反数学惯例。
      【解决方案5】:

      您可以在cppreference.com pow 页面上找到特例列表:

      按照 math_errhandling 中的规定报告错误。

      如果 base 是有限且负数,exp 是有限且非整数,则会发生域错误并且可能会发生范围错误。

      如果 base 为零且 exp 为零,则可能会发生域错误。

      如果 base 为 0 且 exp 为负数,则可能会出现域错误或极点错误。

      如果实现支持 IEEE 浮点算法 (IEC 60559),

      • pow(+0, exp),其中 exp 是一个负奇数,返回 +∞ 并提高 FE_DIVBYZERO
      • pow(-0, exp),其中 exp 是一个负奇数,返回 -∞ 并提高 FE_DIVBYZERO
      • pow(±0, exp),其中 exp 是负数,有限,并且是偶数或非整数, - 返回 +∞ 并引发 FE_DIVBYZERO
      • pow(±0, -∞) 返回 +∞ 并可能提高 FE_DIVBYZERO
      • pow(+0, exp),其中exp为奇数正整数,返回+0
      • pow(-0, exp),其中 exp 是一个正奇数,返回 -0
      • pow(±0, exp),其中 exp 为正非整数或正偶整数,返回 +0
      • pow(-1, ±∞) 返回 1
      • pow(+1, exp) 对任何 exp 返回 1,即使 exp 为 NaN
      • pow(base, ±0) 为任何基数返回 1,即使基数是 NaN
      • pow(base, exp) 如果 base 为有限且为负且 exp 为有限且非整数,则返回 NaN 并引发 FE_INVALID。
      • pow(base, -∞) 为任何 |base| 返回 +∞
      • pow(base, -∞) 对任何 |base|>1 都返回 +0
      • pow(base, +∞) 为任何 |base| 返回 +0
      • pow(base, +∞) 为任何 |base|>1
      • 返回 +∞
      • pow(-∞, exp) 如果 exp 为负奇数,则返回 -0
      • pow(-∞, exp) 如果 exp 是一个负的非整数甚至整数,则返回 +0
      • pow(-∞, exp) 如果 exp 是正奇数,则返回 -∞
      • pow(-∞, exp) 如果 exp 是正非整数甚至整数,则返回 +∞
      • pow(+∞, exp) 为任何负数返回 +0
      • pow(+∞, exp) 对任何正的 exp 返回 +∞ 除非上面指定,如果任何参数是 NaN,则返回 NaN

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-21
        • 2020-01-07
        • 2011-10-23
        • 2021-12-21
        • 2023-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多