Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.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#中执行位运算时,为什么必须强制转换0(零)?_C#_Bitwise Operators - Fatal编程技术网

在C#中执行位运算时,为什么必须强制转换0(零)?

在C#中执行位运算时,为什么必须强制转换0(零)?,c#,bitwise-operators,C#,Bitwise Operators,我使用以下代码将我解压缩的12位值从1.5字节扩展到16位: word[0] |= ((word[0] & 0x800) != 0 ? (Int16)(-4096) : (Int16)0); 如果我没有将最后一个0强制转换为Int16,编译器会抱怨如下: Warning 1 Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first Er

我使用以下代码将我解压缩的12位值从1.5字节扩展到16位:

word[0] |= ((word[0] & 0x800) != 0 ? (Int16)(-4096) : (Int16)0);
如果我没有将最后一个0强制转换为Int16,编译器会抱怨如下:

Warning 1   Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first
Error   2   Cannot implicitly convert type 'int' to 'short'. An explicit conversion exists (are you missing a cast?)

为什么会这样?我知道C#在执行逐位运算时会将所有内容转换为int,但通常情况下,整数常量会自动指定正确的类型。例如,如果我将零赋给一个float,我就不必首先将它转换为float。我是一名C程序员,所以在回答时请记住:-)

C中唯一的整数文本类型是
int
uint
long
ulong
(,第2.4.4.2节)。任何文字(如
0
)的类型只能推断为这4种文字中的一种(并且在没有任何额外指示的情况下,它是
int

那么,为什么:

short s = 0;
工作?这是由于隐式常量表达式转换(第6.1.9节):

int
类型的常量表达式(§7.19)可以转换为类型
sbyte
byte
short
ushort
uint
ulong
,前提是常量表达式的值在目标类型的范围内

但是,我们在这里使用的不是一个常量表达式。因此,所有传统的C#打字规则都发挥了作用;分析条件运算符(第7.14节)时,类型为:

bool ? short : int;

编译器(不能使用上述常量表达式规则)决定该表达式的类型为
int
,因为
short
可以隐式转换为
int
,但不能反之亦然。

这是因为文本
0
被解析为
int
,而不是
short
,而
int
不能隐式转换为
short
,因此,你必须手动施放。你不必将零施放为浮点,因为
int
可以隐式转换为
float
@GSerg。为什么你在评论中提到
float
?@HamletHakobyan,因为OP想知道为什么将零分配给浮点可以不进行施放。除了@FrédéricHamidi的评论之外条件运算符要求
true
false
部分都必须隐式转换为结果类型。好的,但是你能解释一下为什么C#不支持文本短字符吗?当编译器可以轻松地检查文本是否适合短文本时,让您强制转换文本有什么意义?我明白它在做什么,我想知道为什么。另外,你说表达式不是常量,但我不清楚你指的是哪一部分。@MoJo-我认为他们认为常量表达式规则在大多数情况下都是足够的(在我的回答中,将一个literal
int
直接赋值给一个
short
变量)。他们本可以支持更多类型的文字(例如
0s
可能,对于
short
literal),但他们没有。因为我没有参加过任何语言设计会议,所以我不能给出一个明确的“为什么”。@MoJo-re:这个恒常的表达,我同意我在回答中没有强调得太好。但基本上,我们考虑的是整个条件运算符(
?:
)-因为条件(
(word[0]&0x800)!=0
)不是常数,所以整个表达式不是常数。如果我们写
short s=false?0 : 1;
,条件运算符本身是一个常量表达式(类型为
int
),因此,由于上述规则,同样可以编译。@MoJo-最后,如果您想了解有关常量表达式的更多信息,有一个完整的部分(7.19,在上面的引用中)讨论常量表达式是什么。谢谢Damien。我明白你现在的意思了,条件运算符使零也成为条件的,即使它是一个编译时常量,在C中也是如此。所以如果我使用if()语句,那么其中的赋值会被认为是条件的还是常量的?