需要pow(-1,1.2)为1

时间:2011-06-13 00:54:36

标签: c++ math numerical-methods pow

我正在使用带有GCC和GSL的math.h。我想知道如何评估它?

我希望pow函数将pow(-1,1.2)识别为((-1)^ 6)^(1/5)。但事实并非如此。

有人知道会识别这些的c ++库吗?也许有人可以分享他们可以分享的分解程序。

6 个答案:

答案 0 :(得分:11)

在数学上,pow(-1, 1.2)根本没有定义。没有负数的小数指数的幂,我希望没有库只会为这样的表达式返回一些仲裁值。你还会期待像

这样的东西吗?
pow(-1, 0.5) = ((-1)^2)^(1/4) = 1

这显然是不可取的。

此外,浮点数1.2甚至不等于6/5。最接近1.2的双精度数是

1.1999999999999999555910790149937383830547332763671875

鉴于此,您现在对pow(-1, 1.2)会有什么结果?

答案 1 :(得分:9)

如果你想将负数增加到权力 - 特别是分数权力 - 使用cpow()方法。您需要包含<complex>才能使用它。

答案 2 :(得分:3)

好像你正在寻找pow(abs(x), y)


说明:你似乎在考虑

x y =(x N (y / N)

如果我们选择N === 2,那么你有

(x 2 y / 2 =((x 2 1/2 ÿ

但是

(x 2 1/2 = | x |

代替

| X | ý

这是一个延伸,因为上述操作仅适用于非负x,但您是选择使用该假设的人。

答案 3 :(得分:1)

听起来你想要执行复杂的力量(cpow()),然后取其后的幅度(abs())。

>>> abs(cmath.exp(1.2*cmath.log(-1)))
1.0
>>> abs(cmath.exp(1.2*cmath.log(-293.2834)))
913.57662451612202

答案 4 :(得分:1)

pow(a,b)通常被视为,定义为exp(log(a)*b),其中log(a)是a的自然对数。 log(a)没有为实数中的&lt; = 0定义。因此,您需要为负数a和整数b和/或b=1/(some_integer)编写具有特殊情况的函数。对于整数b来说,特殊情况很容易,但对于b=1/(some_integer),它很容易出现四舍五入的问题,就像Sven Marnach指出的那样。

也许您的域pow(-a,b)应始终为-pow(a,b)?但是你只需要实现这样的功能,所以我认为这个问题需要更多的解释。

像duskwuff建议的那样,一个更强大和“数学”的解决方案是使用复杂函数log和exp,但它比表面看起来更“复杂”(请原谅我的双关语)(即使有{{1}功能)。如果你必须计算很多pow(),它会慢得多。

现在有一个复杂数字的重要问题,可能与您的问题域相关或不相关:完成后,cpow的结果不是一个,但通常一些复数,但是在你关心的情况下,其中一个将是复数,具有接近零的虚部(由于舍入误差,它将为非零),你可以简单地忽略和/或不在你的代码中计算

为了演示它,请考虑pow(a,b)是什么。这是pow(-1,.5)的数字,X。你猜怎么着?有两个这样的数字:X^2==-1i。通常,-i只有pow(-1, 1/N)解决方案,但您只对其中一个感兴趣。

如果N的所有结果的虚部都很重要,则表示您传递了错误的值。对于您描述的范围内的单精度浮点值,1e-6 * max(abs(a),abs(b))将是定义“足够大”阈值的良好起点。极端的“错误值”将为pow(a,b),它会返回pow(-1,0.5)(实际为0 + 1i,虚部为0。这里假想部分相对于输入和实部很大,所以你知道你搞砸了你的输入值。

1的任何合理的单一返回结果实现中,cpow()可能会返回类似cpow(-1,0.3333)的内容,并忽略具有重要虚部的其他两个值。所以你可以拿出那个真正的价值而这就是你的答案。

答案 5 :(得分:0)

使用std::complex。没有它,团结的根源就没有多大意义。有了它,它们就非常有意义。