为什么没有pow(sqrt(-1),2)返回-1?

时间:2015-06-09 12:59:26

标签: c++ cmath

相反,此操作返回-1.IND,因为sqrt(-1)返回-1.IND。这个sqrt为负值返回的C++ reference上提到的域错误是否保留了实际上 i 的信息?

是否有某种方法可以对所有负数执行此操作,以便返回正确的值,即pow(sqrt(-36), 2)将返回-36?

5 个答案:

答案 0 :(得分:13)

您可以使用std::complex来实现目标,例如:

#include <complex>
#include <iostream>

int main() {
  const std::complex<double> result = 
    std::pow(std::sqrt(std::complex<double>(-36,0)), 2);
  std::cout << result << std::endl;
  std::cout << "Real part = " << result.real() << std::endl;
}

输出:

(-36,0)
Real part = -36

请注意,此处使用了std::sqrt(std::complex)

您遇到的行为背后的原因是sqrt的签名,即:

  

double sqrt(double x);

     

float sqrt(float x);

     

long double sqrt(long double x);

     

double sqrt(T x); //整数类型的额外重载

这意味着无论使用哪种原型,你都没有比nan(或+ -inf)更好的东西,因为返回类型不能支持虚部。这就是std::complex存在的原因。

因此,sqrt(-1)可能会被nan替换,pow()无法处理,因此-1会保持不变,因为指数。因此,在致电sqrt()并且pow()无法对此进行任何操作后,信息已经丢失。

答案 1 :(得分:6)

因为您正在调用函数double sqrt(double),而double返回值只能存储实数,无穷大(带符号)或NaN。 i 没有任何代表。

如果要存储复数,请使用std::complex

答案 2 :(得分:4)

来自this sqrt reference page

  

如果参数小于-0,则引发FE_INVALID并返回NaN。

然后从this pow reference page

  

...如果任何参数是NaN,则返回NaN

因此,您无法将pow(sqrt(x), y)用于任何否定的真实x

答案 3 :(得分:3)

std::sqrt is defined返回域错误的实现定义错误。在这种情况下,.on('click', '.chkMarkCurrentTime', function () { if ($(this).prop('checked')) { //ON chart.xAxis[0].addPlotLine({ color: '#ddd', width: 1, value: new Date().getTime(), id: 'plot-line-1' }); } else { //OFF chart.xAxis[0].removePlotLine('plot-line-1'); } }) 是域错误。

std::pow is also defined返回域错误的实现定义错误。

因此,接收(arg := -1) < -0是一个合理的解决方案。

正如神秘指出你需要一个复杂的数字库。

答案 4 :(得分:0)

如果你可以使用C ++ 14,你可以使用文字运算符来表示复杂的:#include

<complex>
#include <iostream>

int
main()
{
  using namespace std::literals::complex_literals;
  auto z = std::pow(std::sqrt(-36.0 + 0.0i), 2.0);
  std::cout << z << '\n';
}

运行这个我得到:

ed@bad-horse:~$ ./cpow 
(-36,4.40873e-15)

我知道最近gccclang支持这一点。看起来VS2015也是如此。

这实际上是一个后C ++ 14添加,但它仍然在std命名空间而不是experimental