关于0x80000000为什么等于-2147483648和负数在内存上储存的问题

1·先说明负数怎么储存

(1)十进制负数是以其补码储存在内存上。

验证:求-8在内存上以二进制形式1的个数

思路是:拿变量,令值为1,与-8的二进制码的每一位做与运算,若与运算结果为1,则该位为1。

代码:


 
 
  1. int NumberOf1(int n) {
  2. int count = 0;
  3. unsigned int value = 1;
  4. while ( value != 0) {
  5. if ( value&n) {
  6. count++;
  7. }
  8. value = value << 1; //左移右边补0,当移完32为value为0.
  9. }
  10. return count;
  11. }

结论:

输入-8,结果为29。

在32位系统上,-8的储存

-8的储存是以-8的补码,储存在内存上。

-8的原码 1000 0000 0000 0000 0000 0000 0000 1000

取反 由于第一位是符号位 不用改变 得:1111 1111 1111 1111 1111 1111 1111 0111 

补码=反码+1 得::1111 1111 1111 1111 1111 1111 1111 1000 

得到1的数量正好为29,所以-8的补码就是-8储存在内存上的二进制码

(2)但是在十六进制,负数在内存中储存的是原码

验证:

对int test = 0x80000001 (对应十进制为-1) 检查其内存上的1的个数,发现只有2个1

故内存上原码为  1000 0000 0000 0000 0000 0000 0000 0001.

对十六进制的-8也是2个1


(3)我们来看看0x80000000的输出

0x80000000 的二进制位

原码 1000 0000 0000 0000 0000 0000 0000 0000

若最高位为符号位,则为-0,可是输出int i = 0x80000000 发现i= -(2^31)

原因是在十六进制中负数的二进制原码的最高位是符号位,后面的31位为序号位,不是值位。1后面的000 0000 0000 0000 0000 0000 0000 0000,表示序号1,表示负数中,从小到大的第一位。

由于int的最小值为-2^31,排在负数从小到大的序号1,所以int i = 0x80000000 输出为 -(2^31)

我们来看看0xFFFFFFFF

原码 1111 1111 1111 1111 1111 1111 1111 1111

最高位为1 ,为负数,序号位为第(2^31)-1位  (111 1111 1111 1111 1111 1111 1111 1111=(2^31-1) 所以0xFFFFFFFF为负数从小到大 第2^31-1位 ,即

-2^31+2^31-1= -1    

输出int i = 0xFFFFFFFF 为 -1 符合

(4)十进制的补码也符合 符号位+序号位的原则

就拿-8来做例子:

-8的补码:1111 1111 1111 1111 1111 1111 1111 1000 可以看出最高位为1 序号位为第2^(31)-8位,(111 1111 1111 1111 1111 1111 1111 1000 = 2^(31)-8 )

则该补码表示的值为2^31- 2^(31)-8 = -8  符合

花费了2~3个小时去查阅相关内容,发现,目前较少相关信息,总结了一下发在这,是对自己学习成果的尊重,同时也希望对大家有点用。

觉得写得不错的点个赞,留个言。欢迎指正

------------------------------------------------------------------------

相关知识点补充:

十六进制用最高位作为符号位,1位负数,0为正数。


负数的位右移运算:

原则:若右移的数字为负值,则向右移动N位同时N个1补充在左边

若为正值,则以N个0补充在左边

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有符号数和无符号数在内存中存放方式略有不同。 对于无符号数(如 `unsigned char`、`unsigned int` 等),它们的二进制表示直接对应了它们的值,例如 `0x01` 表示十进制的 1,`0xFF` 表示十进制的 255。因此,无符号数在内存中的存放方式与它们的二进制表示一致。 例如,对于一个 `unsigned char` 类型的变量,它会占用一个字节(8 比特)的内存空间,其中的每一位都对应了一个二进制位。例如,二进制数 `0000 0001` 对应了十进制数 1,二进制数 `1111 1111` 对应了十进制数 255。因此,无符号数在内存中的存放方式就是直接将对应的二进制数存储到内存中。 对于有符号数(如 `char`、`int` 等),它们的二进制表示包含了符号位,即最高位为符号位,0 表示正数,1 表示负数。例如,二进制数 `1000 0000` 表示的是 -128(在大多数机器上),而不是 128。因此,在内存中存储有符号数时,需要先将其转换为补码再进行存储。 例如,对于一个 `char` 类型的变量,它同样占用一个字节的内存空间,其中的第 8 位为符号位,而第 1 到第 7 位表示该数字的绝对值。例如,十进制数 -1 在内存中的表示为原码 `1000 0001`,反码 `1111 1110`,补码 `1111 1111`。因此,-1 在内存中的存放方式就是将其补码 `1111 1111` 存储到内存中。 需要注意的是,在进行有符号数和无符号数之间的类型转换时,需要非常小心,否则可能会导致意想不到的错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值