2017-09-16 60 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,行爲是不同的。 –