2012-12-09 30 views
5

我有以下的部門,我需要經常做的事:如何在兩次冪時將一個分區變成按位移?

int index = pos/64; 

司可以在CPU級別昂貴。我希望有一種方法可以做到這一點,按位移。我還想了解你如何從分工轉變爲換位,換句話說,我不想只記住按位表達。

+1

'pos /(2^6)'=>'pos >> 6'; 'pos /(2^1)'=>'pos >> 1' – irrelephant

+1

在cpu級別,分區不應該很貴。 – ceklock

+0

你可能錯誤地認爲「部門很貴」。請記住着名的唐納德克努特報價:[不成熟的優化是所有邪惡的根源](http://en.wikipedia.org/wiki/Program_optimization) – paulsm4

回答

7

int index = pos >> 6會做到這一點,但這是不必要的。任何合理的編譯器都會爲你做這種事情。當然,Sun/Oracle編譯器會。

一般規則是i/(2^n)可以用i >> n實現。同樣的i*(2^n)i << n

如果您簽署了i,您需要關注負數表示。例如。二進制補碼產生合理的結果(如果右移是算術符號位複製)。符號大小不。

+0

你是對的 - 做「轉移」以避免「分裂」是不必要的,也是錯誤的。恕我直言... – paulsm4

+3

編譯器將只會優化,如果它是一個文字。如果它是一個變量,它不會優化任何東西,並且可以通過邏輯輕鬆地強制該變量是二的冪。然後你自己做優化。 – TraderJoeChicago

2

編譯器會以最有效的方式爲您實現它,只要您明白您需要什麼,並要求編譯器完成該操作即可。如果在這種情況下shift是最有效的方式,編譯器將使用shift。

但請記住,如果您正在執行簽署師(即pos簽署),那麼就不能完全由單獨的轉變來實現。自行移位將產生無效結果,負值爲pos。如果編譯器決定對這個操作使用移位,它還必須對中間結果執行一些移位後修正,以使其與語言規範的要求一致。由於這個原因,如果你真的希望儘可能提高分工的效率,你必須記住不要盲目地使用簽名類型。儘可能使用無符號類型,只有在必要時才使用簽名類型。

P.S. AFAIK,Java實現了Euclidean劃分,這意味着上述評論不適用於Java。歐幾里得除法是通過2's-complement表示中的負除數的移位而正確執行的。上述評論將適用於C/C++。

相關問題