[英]Signed right shift: which compiler use logical shift
我用 Visual Studio、Ubuntu 的 GCC、英特爾編譯器、MinGW 測試了右移。 所有的符號位都移位。 我猜 Xcode 的 GCC 也是如此。
我知道這種行為是特定於實現的,但看起來所有主要的桌面/服務器編譯器都實現了算術轉換。 是否有任何廣泛使用的編譯器不會改變符號位?
謝謝你。
C 運行在許多不同的體系結構上。 我的意思是很多不同的架構。 您可以在嵌入式 DSP 和 Cray 超級計算機上運行 C 代碼。
人們認為理所當然的 C 標准中的大多數“實現定義”部分實際上只會破壞晦澀的架構。 例如,有 DSP 和 Cray 超級計算機,其中CHAR_BIT
是 32 或 64 之類的大數字。因此,如果您在 x86 上嘗試您的代碼,並且如果您喜歡使用 PowerPC、ARM 或 SPARC,則不太可能遇到任何非常奇怪的情況。 沒關系。 如今,大多數代碼將始終運行在具有二進制補碼整數和算術移位的面向字節的體系結構上。 我毫不懷疑,在可預見的未來,任何新的 CPU 架構都是一樣的。
但是讓我們看看整數的兩種最常見的表示形式:二進制補碼和一個補碼:
switch ((-1) >> 1) {
case 0:
case -0:
puts("Hello, one's complement world!");
// Possibly sign-magnitude.
break;
case -1:
puts("Hello, two's complement world!");
break;
default:
puts("Hello, computer without arithmetic shift");
break;
}
不要出汗。 當你想分割時,只需堅持/
,當你需要轉移時,就堅持>>
。 即使是糟糕的編譯器也擅長優化這些操作。 (請記住,如果x
是負數,則x/2 != x>>1
,除非您使用的是補碼機,這幾乎肯定不是真的。)
該標准確實保證如果(int) x
不是負數,則(int) x >> n == (unsigned) x >> n
,因此編譯器沒有太多空間可以做一些完全出乎意料的事情。
Cray C 編譯器默認對有符號值進行邏輯右移,但有一個選項可以進行算術移位。
通常,可以安全地假設有符號右移是算術。
通常,它更多地取決於編譯器使用的目標架構。 如果 arch 同時具有算術(有符號)和邏輯(無符號)移位指令,則該 arch 的 C 編譯器將使用適當的。 另一方面,如果它只有邏輯移位,C 編譯器將只使用它,即使它不會對負值“做正確的事情”,因為 C 規范允許編譯器做任何事情。
據我所知, >> 運算符進行算術移位。 然而,對有符號和無符號整數執行移位的方式有所不同 - 有符號將擴展 MSB(通常是符號位)而無符號則不會(它們始終為非負,因此符號位始終為零)。
編輯: “通常”適用於我上面寫的所有內容;)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.