【问题标题】:why (0+0i)^{0} == (nan, nan) in c++为什么 (0+0i)^{0} == (nan, nan) 在 C++
【发布时间】:2013-06-26 09:17:04
【问题描述】:

看一下自爆的代码:

#include <complex>
#include <iostream>

int main()
{
    std::cout << std::pow( std::complex<double>(0,0), std::complex<double>(0,0) ) << "\n";
    std::cout << std::pow( std::complex<double>(0,0), double(0) ) << "\n";

    return 0;
}

g++(4.8.1) 给出的输出为

(nan,nan)
(-nan,-nan)

虽然 clang++(3.3) 给出了输出

(-nan,-nan)
(-nan,-nan)

但我期待 (1.0, 0.0)。

谁能解释一下?

【问题讨论】:

  • @Mr.Alien:确实如此,我不明白他为什么期待他所期待的。
  • @PlasmaHH 这就是他问的原因:)
  • zerozero 未定义:math.utah.edu/~pa/math/0to0.html
  • @Mr.Alien:我不认为他在问他为什么期待 1.0,0.0 ...
  • 在数学上应该是 (1, 0),但是为什么这里 g++/clang++ 给出 (nan,nan)——这就是问题所在。

标签: c++ numeric nan complex-numbers exponential


【解决方案1】:

正如 Fred Larson 正确的 points out documentation 所说:

pow(0, 0) 的结果是实现定义的。

从数学上讲,这是有道理的,因为我们有一个矛盾的情况,N^0 应该始终是 1,但对于 N &gt; 00^N 应该始终是 0,所以你不应该对数学结果有任何期望这要么。这个Wolfram Alpha 论坛帖子有更多细节。

复数的虚部不是zero的情况是more complex的情况。如果x^y 中的x 是实数,那么它也应该是未定义的,但如果x 有一个虚部,那么它看起来就不再是未定义的了。

【讨论】:

  • 在 Python 中也可以吗?你检查了吗?
【解决方案2】:

根据std::pow documentation

返回值
由幂(exp 或 iexp)提高的基数。
如果 base 为 0 且 exp 小于或等于​0​,则会发生域错误。 在这种情况下返回 NAN。 [...]

在您的代码中,由于复数 0 + 0 *i 仍为 0,因此您的 base 和 exp 都为 0。所以 NaN 似乎是预期的。

感谢@Fred Larson,并根据overloaded std::pow for std::complex

计算复数 x 的复数幂 y。该操作定义为 exp(y · log(x) )。沿负实轴存在分支切割。 pow(0, 0) 的结果是实现定义的。

【讨论】:

  • 实际上,我不确定引用是否相关,因为 pow()std::complex 覆盖。但是这个是:en.cppreference.com/w/cpp/numeric/complex/pow 注意,“pow(0, 0) 的结果是实现定义的。”
  • @FredLarson 哪个可以解释视觉工作室的捐赠 (1,0)(1,0)?
  • @FlorisVelleman:听起来它可以返回任何它想要的东西。
  • @FredLarson 感谢您指出这一点,我更新了帖子。
  • 在这里发帖之前,我已经阅读了c++标准草案n3376,但是没有找到这个;非常感谢。
猜你喜欢
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
  • 2015-11-27
  • 2012-04-24
  • 2011-06-19
相关资源
最近更新 更多