Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.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#';s二进制运算符总是返回int,而不管其输入的格式如何?_C#_Operators_Byte - Fatal编程技术网

为什么C#';s二进制运算符总是返回int,而不管其输入的格式如何?

为什么C#';s二进制运算符总是返回int,而不管其输入的格式如何?,c#,operators,byte,C#,Operators,Byte,如果我有两个bytesa和b,为什么: byte c = a & b; 生成有关将字节转换为int的编译器错误?即使我在a和b前面放了一个显式强制转换,它也会这样做 另外,我知道,但我真的不知道它在这里是如何应用的。这似乎是运算符&(字节操作数,字节操作数2)的返回类型的问题,编译器应该能够像任何其他运算符一样对其进行排序 为什么C#的位运算符总是返回int,而不管其输入的格式如何 我总是不同意。这是可行的,a&b的结果是类型long: long a = 0xffffffffffff;

如果我有两个
byte
s
a
b
,为什么:

byte c = a & b;
生成有关将字节转换为int的编译器错误?即使我在
a
b
前面放了一个显式强制转换,它也会这样做

另外,我知道,但我真的不知道它在这里是如何应用的。这似乎是
运算符&(字节操作数,字节操作数2)
的返回类型的问题,编译器应该能够像任何其他运算符一样对其进行排序

为什么C#的位运算符总是返回int,而不管其输入的格式如何

我总是不同意。这是可行的,
a&b
的结果是类型
long

long a = 0xffffffffffff;
long b = 0xffffffffffff;
long x = a & b;
如果一个或两个参数是
long
ulong
uint
,则返回类型不是
int


为什么C#的按位运算符在输入为字节时返回int

byte&byte
的结果是一个int,因为在byte上没有定义
&
运算符。()


运算符存在于
int
中,并且还有一个从
字节到
int
的隐式转换,因此当您写入
字节1和字节2时,这实际上与写入
((int)字节1)和((int)字节2)相同
结果是一个
int

这是因为&是在整数上定义的,而不是在字节上定义的,编译器会隐式地将两个参数转换为int。

二进制运算符不是为字节类型(以及其他类型)定义的。事实上,所有二进制(数字)运算符仅对以下本机类型起作用:

  • int
  • 尤因
  • 长的
  • 乌龙
  • 浮动
  • 双重的
  • 十进制
如果涉及任何其他类型,它将使用上述其中一种


对预定义的+、–、*、/、%、&、|、^、=、、!=、>、=、的操作数进行二进制数字提升,这种行为是IL设计的结果,IL是所有.NET编译器生成的中间语言。虽然它支持短整数类型(byte、sbyte、short、ushort),但对它们的操作数量非常有限。加载、存储、转换、创建数组,仅此而已。这不是偶然的,这些操作可以在32位处理器上高效执行,早在IL设计时,RISC就是未来

二进制比较和分支操作仅适用于int32、int64、本机int、本机浮点、对象和托管引用。这些操作数在任何当前CPU内核上都是32位或64位,确保JIT编译器可以生成高效的机器代码

您可以在ECMA335,第一部分,第12.1章和第三部分,第1.5章中了解更多信息



关于这一点,我写了一篇更广泛的文章。

请看,或者你可能会有你的答案……基本上,这是因为C#设计人员确定成本太高,无法将位运算符(不能溢出)的规则与算术运算符(可以溢出)的规则分开编写。要证明让编译器插入隐式强制转换是安全的,这很简单,因为值总是在较窄类型的范围内。但显然,指定、编写和测试该行为的成本被认为大于收益。实际上,它与位运算符是否无关。根本没有作用于字节类型的运算符。@PhilippeLeybaert:无论CLR是否定义了此类运算符,都不会阻止C#像它那样运行,就像C#接受每一个不重载
=
的类类型并假装它有一个重载来检查该类型的两个对象一样。是,但这并不能解释为什么结果是整数。@Philippe Leybaert:增加了额外的段落。嗯?它准确而明确地解释了为什么结果是整数。@fearofahackplanet:是的,现在它是整数了。但在添加额外的段落之前,这是一个非常完整的答案,尽管我发现有符号32位int的
~
运算符与数字的作用很有趣,就好像它是无符号8位字节一样。这让我怀疑这种隐式转换是否需要处理成本。。。我最终对其执行逐位操作的数据类型通常是旧的图像格式(如位平面合并/拆分),因此通常需要处理数万字节。@Nyerguds对本机类型的转换可能是在编译到IL的过程中完成的,因此您在C#中定义的任何字节在IL中都会显示为uint。这意味着除了在编译时影响非常小之外,不会对性能造成任何影响。