繁体   English   中英

C#奇怪的部门问题

[英]C# Weird division issue

我有一种int和一种uint类型:

int tempA = 0xbc000669;
uint tempB = 0xbc000669;

当我做

tempA /0x2000 ,想向右移动13,它给我0xfffde001

tempB / 0x2000 ,也想向右移动13,它给了我正确的答案: 0x0005e000

有人知道为什么签名后我得到一个错误的答案吗? 我没想到分裂会溢出吗? 谢谢

在声明中

tempA / 0x2000

编译器会看到int类型的变量和数字文字值。 由于对int类型的除法需要两个int类型的操作数,因此值0x2000也会自动转换为int。 该语句评估为

(int)0xbc000669 / (int)0x2000

这是-1140849047 / 8192等于-139263

十六进制的-139263是FFFDE001(至少在32位值上)

实际上0xbc000669 不能包含在一个int ,更确切的说它代表一个negative integer 我们知道一个int使用第32nd bit作为sign bit 0cbc000669有最显著半字节为0xb其等于1011 - >的32nd bit1 ,实际是一个负整数。 所以:

int tempA = 0xbc000669;

将使tempA等于-1140849047 ,将此数字右移13个二进制数字将返回获得的准确结果: 0xfffde001

如果您像这样将tempB声明为uint

uint tempB = 0xbc000669;

它可以完全包含在uint因为uint不使用第32nd bit作为符号位。 实际数字是一个positive integer ,其值是3154118249 ,将该值右移13个二进制数将得到准确的结果为0x5e000

从规范中关于整数除法的内容来看:

除法将结果舍入为零,结果的绝对值是最大可能的整数,该整数小于两个操作数的商的绝对值。 当两个操作数具有相同的符号时,结果为零或正;而当两个操作数具有相反的符号时,结果为零或负。

如果我正确地解释了该文本,则会导致以下情况:在第一个示例中,带符号的int值设置了符号位; 第二个数字(0x2000)为正,因此结果为零或负。

解释此问题的最佳方法是显示位如何工作。 Wikipedia上有关签名数字表示的文章对此进行了很好的介绍。 您将要阅读关于二进制补码的部分。

我认为期望是人们希望-1和1的二进制数相同,但-1的符号位为1。 不是这种情况。 1,例如

0000 0000 0000 0000 0000 0000 0000 0001

-1是

1111 1111 1111 1111 1111 1111 1111 1111

人们直觉上认为-1实际上是-127:

-127 == 1000 0000 0000 0000 0000 0000 0000 0001

现在,让我们看看您得到的答案。 在有符号除法中,当您向右移动时,实际上实际上是将数字的左侧填充1并加1。这就是您在结果中看到的结果。

0xFFFDE001 = 1111 1111 1111 1101 1110 0000 0000 0001
0x0005E000 = 0000 0000 0000 0101 1110 0000 0000 0000

您会注意到,它们都是一样的,除了最上面的(来自已签名部门的)左边有13 1的填充,末尾有1的填充。

对于带符号整数,要记住的重要一点是,二进制补码会更改位的顺序,因此,除符号位外,-50不具有与+50相同的位模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM