【问题标题】:Why is -0.x^0.x -nan(ind)为什么是 -0.x^0.x -nan(ind)
【发布时间】:2016-05-26 14:51:48
【问题描述】:

我的程序由于某种原因出现故障,我发现这是因为我的计算归结为 pow(-0.2, 0.2),它在调用时解析为 -nan(ind)。

如果它是一个非常小或非常大的数字,我会理解,但为什么 C++ 将此计算解析为 -nan(ind)?有没有办法让它输出正确的值(-0.72477966367)?

【问题讨论】:

  • 你只需要解决x ^ (1/5),还是指数也可以是其他数字?
  • 指数也可以是其他数字,这使事情变得复杂:\
  • x ^ (k / odd_number)的形式吗?
  • 这是不允许的,因为在大多数情况下,负值的非整数指数会给出复杂的结果。虽然理论上有一些指数会给出真实的结果(包括 1/5),但允许它们是没有意义的,因为它们不能用浮点数精确表示。
  • 如果你想要一个复杂的结果,你可以使用带有std::complex参数的std::pow的重载。

标签: c++ nan


【解决方案1】:

我猜你想计算一个负数的五次方根,可以写成 x ^ (1/n)。但是 C 和 C++ pow 不支持这一点。请参阅pow 文档:

如果底数是有限的负数,指数是有限的但不是整数值,则会导致定义域错误。

【讨论】:

  • 谢谢,遗憾的是,我只是在发布问题一分钟后才明白这一点,但我认为无论如何我都不应该删除它。有问题的是,这对我的程序非常重要。你知道我可以解决这个问题的方法吗?
  • @FrédéricHamidi 在 Python 2 上 (-0.2) ** 0.2 引发 ValueError。在 Python 3 上,它返回 (0.5863590650926145+0.4260147974712481j)
  • @kenny,在我的 Python 3.4.3 上,-0.2 ** 0.2 产生 -0.7247796636776955(编辑:我现在明白了。括号很重要。)
  • 我猜想处理倒奇数指数的特殊情况被认为不够重要,不足以证明复杂的实现和规范是合理的。您需要自己检测和处理这些情况。
  • @Suma:它的定义也不明确,因为0.2 不完全是五分之一(由于二进制浮点通常存在困难)。所以任何解释它的东西都必须有点神奇。
【解决方案2】:

你可以像这样让它输出正确的值:

template <typename T> int sgn(T val) {
    return (T(0) < val) - (val < T(0));
}

template <class T, class U> auto safe_pow(T val, U p) -> decltype(pow(val, p)) {
    return pow(abs(val), p) * sgn(val);
}

auto x = safe_pow(-0.2, 0.2);

Live Demo

【讨论】:

  • 谢谢,但是当我尝试实现此代码时,我收到错误 C3551 和 4430:如果使用尾随返回类型,则前导返回类型应为单个类型说明符 'auto'(而不是 ' int') 缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int 我已经尝试了一些东西但没有设法修复它,你有没有机会告诉我如何让它工作?
  • @Milan 已修复...在safe_pow 之前缺少一个auto。添加了现场演示链接。
  • 你太棒了。太感谢了。不敢相信我没想到要在那里添加自动,哈哈。
  • 请注意,这处理 1/odd 正如 OP 所期望的那样,但即使没有真正的答案,它也会提供答案,例如 safe_pow(-3, 0.5555)
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 2014-11-06
  • 1970-01-01
  • 2022-08-22
  • 2014-11-09
  • 2013-06-26
相关资源
最近更新 更多