计算能力为-1

时间:2017-09-16 17:23:27

标签: language-agnostic

是否存在实施(-1)^n * a的惯用语?

pow(-1,n) * a的显而易见的选择似乎很浪费,(1-2*(n%2)) * a也很丑陋而且效率也不高(两次乘法和一次加法,而不只是设置符号)。我想我现在会使用n%2 ? -a : a,但引入条件似乎也有点可疑。

2 个答案:

答案 0 :(得分:1)

对您的编程语言,编译器和CPU做出某些假设......

重复传统的 - 正确的 - 智慧,除非你的分析工具说它是一个瓶颈,否则不要考虑优化这类事情。如果是这样,n % 2 ? -a : a可能会生成非常有效的代码;即一个AND,一个针对零的测试,一个否定和一个条件移动,AND +测试和否定独立,因此它们可以同时执行。

另一个选项看起来像这样:

zero_or_minus_one = (n << 31) >> 31;
return (a ^ zero_or_minus_one) - zero_or_minus_one;

这假设32位整数,算术右移,整数溢出定义的行为,二进制补码表示等。它也可能编译成四个指令(左移,右移,XOR和减法),每个之间具有依赖性...但对于某些指令集可能更好;例如,如果您使用SSE指令对代码进行矢量化。

顺便提一下,如果您使用特定语言对其进行标记,那么您的问题将获得批次更多观看次数 - 可能还有更多有用的答案。

答案 1 :(得分:0)

正如其他人所写,在大多数情况下,可读性比性能更重要,编译器,解释器和库比大多数人想象的更优化。因此pow(-1,n) * a可能是您平台上的有效解决方案。

如果您确实遇到了性能问题,那么您自己的建议n%2 ? -a : a就可以了。我没有理由担心条件分配。

如果您的语言具有按位AND运算符,您还可以使用n & 1 ? -a : a即使没有任何优化也应该非常有效。很可能在许多平台上,这是pow(a,b)a == -1b为整数的特殊情况下实际执行的操作。