2017-09-16 94 views
1

实施(-1)^n * a有成熟的习惯用法吗?计算能力为-1

pow(-1,n) * a的明显选择似乎很浪费,(1-2*(n%2)) * a是丑陋的,并不完全有效(两个乘法和一个加法,而不是设置符号)。我认为我现在会用n%2 ? -a : a,但引入一个条件似乎也有点可疑。

+0

如果这是语言不可知的,为什么你使用特定的语法?可能存在一种可以有效处理'(-1)^ n * a'的语言。 – lilezek

+0

我会用pow(-1,n)* a去。读者最容易理解。这很难说,因为你不是在谈论某种特定的语言,但pow()有一些优化/特殊情况已经在它内部完成了。例如,查找一个C实现,它可能与您所期望的完全不同。 –

+0

标记此问题语言不可知的一点是,语言通常就其提供的功能达成一致, 'atan2'或'2 << n'。 – gTcV

回答

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指令来向量化代码。顺便提一句,如果您用特定语言标记,您的问题将获得批次更多意见 - 也许更有用的答案。

0

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

如果你确实有性能问题,你自己的建议n%2 ? -a : a是好的。我没有看到有理由担心有条件的分配。

如果您的语言具有按位AND运算符,那么也可以使用n & 1 ? -a : a,即使没有任何优化,它也应该是非常高效的。在很多平台上,这可能是在a == -1b是一个整数的特殊情况下实际做的。

+0

我非常相信编译器会很快将'n%2'转换为'n&1'。对'pow(-1,n)'不太确定 - 对于非整数n,行为是不同的。 –