[英]Why does the F# Bitwise Operator pad with 1's for signed types?
我在按位操作上看F#doc:
按位右移運算符 。 結果是第一個操作數,其位向右移動第二個操作數中的位數。 偏離最不重要位置的位不會旋轉到最重要的位置。 對於無符號類型,最高有效位用零填充。 對於有符號類型,最高有效位用1填充。 第二個參數的類型是int32。
與C ++語言(也可能是C語言)相比,這種設計選擇背后的動機是什么,其中MSB用零填充? 例如:
int mask = -2147483648 >> 1; // C++ code
其中-2147483648 =
10000000 00000000 00000000 00000000
和掩碼等於1073741824
1073741824 =
01000000 00000000 00000000 00000000
現在,如果你在F#(或C#)中編寫相同的代碼,這確實會填充MSB,你將得到-1073741824。
其中-1073741824 =
11000000 00000000 00000000 00000000
帶符號的移位具有良好的屬性,即右移x對應於floor(x / 2 n )。
在.NET上,有兩種類型操作的CIL操作碼( shr
用於執行有符號的移位, shr.un
用於執行無符號移位)。 F#和C#根據要移位的類型的符號選擇要使用的操作碼。 這意味着如果你想要其他行為,你只需要在移位之前和之后執行數字轉換(由於數據存儲在CLR上的方式實際上沒有運行時影響 - 堆棧上的int32與uint32無法區分) 。
要回答改革后的問題(在評論中):
C和C ++標准沒有定義右移負值的結果(它是實現定義的,或者是未定義的,我不記得哪個)。
這是因為標准被定義為反映基礎指令集的最低公分母。 例如,如果指令集不包含asr
原語,則執行真正的算術移位需要幾條指令。 這是由事實進一步復雜化的是,標准要求一方的或二進制補碼表示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.