什么是正确的方法来获得(-1)^ n?

许多algorithm需要计算(-1)^n (两个整数),通常作为一系列因子。 也就是说,对于奇数n是-1对于偶数n是1 。 在C或C ++环境中,经常会看到:

 #include<iostream> #include<cmath> int main(){ int n = 13; std::cout << std::pow(-1, n) << std::endl; } 

什么更好或惯例? (或者是其他东西),

 std::pow(-1, n) std::pow(-1, n%2) (n%2?-1:1) (1-2*(n%2)) // (gives incorrect value for negative n) 

编辑:另外,用户@SeverinPappadeux提出了另一种基于(全局?)数组查找的替代scheme。 我的版本是:

 const int res[] {-1, 1, -1}; // three elements are needed for negative modulo results const int* const m1pow = res + 1; ... m1pow[n%2] 

如果你想超级迂腐,你可以用(n & 1)代替n % 2 ,用<< 1代替* 2 ,呃我的意思是优化。
所以在8086处理器中计算最快的方法是:

1 - ((n & 1) << 1)

我只是想澄清这个答案来自哪里。 原来的海报alfC发表了很多不同的方法来计算(-1)^ n一些比别人快。
现在,处理器速度与现有处理器一样快,优化编译器的性能同样优秀, 通常我们通过从操作中减less几个CPU周期来实现轻微(甚至可以忽略的)改进,从而提高可读性。
曾经有一次通过编者统治地球,MUL行动是新的和颓废的; 在那个时候,2次手术的权力是无偿优化的邀请。

通常,你实际上并没有计算(-1)^n ,而是跟踪当前的符号(作为一个数字是-11 ),并在每一个操作( sign = -sign )上进行翻转,当你处理你的n按顺序,你会得到相同的结果。

编辑:请注意,我推荐这一部分原因是因为很less有实际的语义值是表示(-1)^n它只是一个方便的方法翻转迭代之间的符号。

首先,我知道最快的是ODRDtesting(在内联方法中)

 /** * Return true if the value is odd * @value the value to check */ inline bool isOdd(int value) { return (value & 1); } 

然后利用这个testing,如果奇数返回-1,否则返回1(这是(-1)^ N的实际输出)

 /** * Return the computation of (-1)^N * @n the N factor */ inline int minusOneToN(int n) { return isOdd(n)?-1:1; } 

最后build议@Guvante,你可以减less乘法,只是翻转一个值的符号(避免使用minusOneToN函数)

 /** * Example of the general usage. Avoids a useless multiplication * @value The value to flip if it is odd */ inline int flipSignIfOdd(int value) { return isOdd(value)?-value:value; } 

许多algorithm需要计算(-1)^ n(两个整数),通常作为一系列因子。 也就是说,对于奇数n是-1,对于偶数n是1。

考虑将该系列评估为-x的函数。

关于什么

 (1 - (n%2)) - (n%2) 

n%2最有可能只会计算一次

UPDATE

其实最简单最正确的方法就是使用表格

 const int res[] {-1, 1, -1}; return res[n%2 + 1]; 

那么如果我们正在进行一系列的计算,那么为什么不在正循环和负循环中处理计算,完全忽略了评估?

泰勒级数展开来逼近(1 + x)的自然对数就是这类问题的一个很好的例子。 每个项有(-1)^(n + 1)或(1)^(n-1)。 没有必要计算这个因素。 你可以通过对每两个项目执行1个循环,或者两个循环,一个用于奇数项,一个用于偶数项,来“分割”问题。

当然,由于计算的本质是实数域的计算,所以您将使用浮点处理器来评估个别项。 一旦你决定这样做,你应该使用自然对数的库实现。 但是,如果由于某种原因,你决定不这样做,它肯定会更快,但不是太多,不要浪费周期来计算-1到n次幂的值。

也许每个人甚至可以在不同的线程中完成。 也许问题可以是vector化的,甚至。