izb*_*izb 1 c# casting bit-manipulation bitwise-operators
我是一名试图迁移到C#的Java程序员,这让我感到有点难过:
int a = 1;
a = 0x08000000 | a;
a = 0x80000000 | a;
Run Code Online (Sandbox Code Playgroud)
第一行编译得很好.第二个没有.它似乎认识到有一个带符号位的常量,并且由于某种原因它决定将结果转换为long,导致错误:
无法将类型'long'隐式转换为'int'.
存在显式转换(您是否错过了演员?)
我到目前为止的修复是:
a = (int)(0x80000000 | a);
Run Code Online (Sandbox Code Playgroud)
哪个涉及演员,但仍然留下警告:
在符号扩展操作数上使用的按位或运算符;
首先考虑转换为较小的无符号类型
以错误/警告/长期自由方式表达此错误的正确C#方式是什么?
Guf*_*ffa 12
一个数值整数literal是int默认的,除非数太大,以适应在一个int和它成为一个uint代替(等为long和ulong).
由于值0x80000000太大而无法放入int,因此它是一个uint值.在a上使用|运算符时int,uint两者都被扩展为,long因为两者都不能安全地转换为另一个.
该值可以表示为int,但是您必须忽略它变为负值.编译器不会默默地执行此操作,因此您必须指示它在int不关心溢出的情况下创建值:
a = unchecked((int)0x80000000) | a;
Run Code Online (Sandbox Code Playgroud)
(注意:这只指示编译器如何转换值,因此没有为转换创建代码int.)
Eri*_*ert 12
我觉得有趣的是,在所有这些答案中,只有一个人实际建议做警告所说的.警告告诉您如何解决问题; 注意它.
在符号扩展操作数上使用的按位或运算符; 首先考虑转换为较小的无符号类型
bitwise或运算符用于符号扩展操作数:int.这导致结果转换为更大的类型:long.小于long的无符号类型是uint.所以警告说的是这样做的; 将符号扩展操作数 - int - 转换为uint:
result = (int)(0x80000000 | (uint) operand);
Run Code Online (Sandbox Code Playgroud)
现在没有符号扩展名.
当然,这只会引发一个更大的问题:为什么你首先将一个有符号整数视为一个位域?这似乎是一件危险的事情.