(-1)^ c在c ++中取幂

Vin*_*ent 2 c++ math optimization

考虑以下形式的收敛系列:

sum(((-1)^n)*something) 
Run Code Online (Sandbox Code Playgroud)

n迭代索引在哪里(n从哪里1开始infinity).

如果我们实现direclty公式,我们std::pow(-1, n)有一个更"快速"的算法技巧来实现它?

Dan*_*her 13

检查n是偶数还是奇数,

(n % 2 == 0) ? 1 : -1;
Run Code Online (Sandbox Code Playgroud)

可以.如果你想避免分支,

1 - 2*(n & 1)
Run Code Online (Sandbox Code Playgroud)

  • @MatsPetersson如果编译器没有用`&1`(在二进制补码机器上)替换`%2`,扔掉它,它就是垃圾.如果在所讨论的平台上位移不快,则乘法应该只保持为1.但我不希望无分支代码更快.两者都应该是一样的. (3认同)

小智 6

我假设它sum(((-1)^n)*something)是伪代码,并且n是一个由sum限制的变量.

让我们把这个符号扩展到sum(n <- [0,1,2,3..], ((-1)^n)*f(n)).你最好的选择可能是首先将它分成两个,你加在一起:

sum(n <- [0,2..], ((-1)^n)*f(n)) + sum(n <- [1,3..], ((-1)^n)*f(n))
Run Code Online (Sandbox Code Playgroud)

在第一个任期,n总是平均的,所以(-1)^n永远都是+1.类似地,在第二个任期,它将永远是-1.我们现在可以重写如下:

sum(n <- [0,2..], f(n)) + sum(n <- [1,3..], -f(n))
Run Code Online (Sandbox Code Playgroud)

由于第二个和中的每个项乘以一个常数,我们可以将该常数移出总和:

sum(n <- [0,2..], f(n)) - sum(n <- [1,3..], f(n))
Run Code Online (Sandbox Code Playgroud)

现在,让我们确保这些资金采取指数相同的序列,并替代2*m2*m+1n:

sum(m <- [0,1..], f(2*m)) - sum(m <- [0,1..], f(2*m+1))
Run Code Online (Sandbox Code Playgroud)

现在我们可以再次统一这些总和:

sum(m <- [0,1..], f(2*m) - f(2*m+1))
Run Code Online (Sandbox Code Playgroud)

或者,如果你想要伪C:

T result = 0;
for(m = 0; m < limit; m+=2) {
    result += f(m);
    result -= f(m+1);
}
Run Code Online (Sandbox Code Playgroud)

这可以为您节省乘法,+1或者-1像大多数人似乎在这里建议的那样.由于你的序列是收敛的,所以加一个额外的术语不应该对答案的正确性产生负面影响.