Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么F#位运算符使用1';签名类型是什么?_C#_C++_F#_History_Bit Shift - Fatal编程技术网

C# 为什么F#位运算符使用1';签名类型是什么?

C# 为什么F#位运算符使用1';签名类型是什么?,c#,c++,f#,history,bit-shift,C#,C++,F#,History,Bit Shift,我在看按位操作的F#doc: 按位右移运算符。这个 结果是第一个带位的操作数 按中的位数右移 第二个操作数。位移位 最不重要的位置不是 旋转到最重要的位置 位置。对于无符号类型,最 有效位用数字填充 零。对于签名类型,最 有效位用1填充。 第二个参数的类型是 int32 这个设计选择的动机与C++语言(也可能是C语言)相比,MSB是用零填充的?例如: int mask = -2147483648 >> 1; // C++ code 其中-2147483648= 10000000 0

我在看按位操作的F#doc:

按位右移运算符。这个 结果是第一个带位的操作数 按中的位数右移 第二个操作数。位移位 最不重要的位置不是 旋转到最重要的位置 位置。对于无符号类型,最 有效位用数字填充 零。对于签名类型,最 有效位用1填充。 第二个参数的类型是 int32

这个设计选择的动机与C++语言(也可能是C语言)相比,MSB是用零填充的?例如:

int mask = -2147483648 >> 1; // C++ code
其中-2147483648=

10000000 00000000 00000000 00000000
掩码等于1073741824

其中1073741824=

01000000 00000000 00000000 00000000
11000000 00000000 00000000 00000000
现在,如果您用F#(或C#)编写相同的代码,这将确实用1填充MSB,您将得到-1073741824

其中-1073741824=

01000000 00000000 00000000 00000000
11000000 00000000 00000000 00000000

回答修改后的问题(在评论中):

< > C和C++标准没有定义正确的移位负值的结果(它是实现定义的,或者是未定义的,我记不起是哪个)。
这是因为标准的定义反映了底层指令集的最低公分母。例如,如果指令集不包含
asr
原语,则强制执行真正的算术移位需要几个指令。标准规定了一个或两个补码的表示,这一事实使情况更加复杂。

有符号移位具有很好的特性,即将x向右移位n对应于地板(x/2n)


在.NET上,这两种类型的操作都有CIL操作码(
shr
执行有符号移位和
shr.un
执行无符号移位)。F#和C#根据被移位类型的符号选择要使用的操作码。这意味着,如果需要其他行为,只需在移位之前和之后执行数字转换(这实际上没有运行时影响,因为数字是如何存储在CLR上的-堆栈上的int32与uint32无法区分)(-1>>1)!=(-1/2)@Oli-是的,在.NET中也是如此。。。我将进行编辑以澄清。@Oli,严格来说,
-1>>1
-1/2
都正确地除以零。不过,他们的取整方式有所不同,移位进行统计取整,整数除法进行小学取整。在假设等价的情况下仍然会导致错误,但这仍然是一种移位-除法等价。Jon,我真的怀疑在任何语言中是否有任何操作可以“正确地除以零”…)呵呵。是的,那是一个有趣的打字错误。