整数的内存表示---记录一道题目

  最近面试,面试官问我的竟然都是程序员宝典里面的C++问题,这里记录一下看程序员宝典过程中遇到的问题,当做一种日记吧。整数无非是负数,正数和0,他们在内存中的二进制表示和原码、反码、补码息息相关。

一、原码、反码、补码的定义

1.原码

正数的原码的符号位为0,负数的原码符号位为1,其他位则表示为是其绝对值的二进制形式。记录几个例子:

X=+1011011       [X]原码=01011011
Y=-1011011         [Y]原码=11011011
[+1]原码=00000001     [-1]原码=10000001
[+127]原码=01111111     [-127]原码=11111111

例如对于-127要求其原码,首先由于它是负数所以符号位是1,然后其绝对值为127所对应的二进制是1111111,所以-127的原码是11111111。

原码表示的整数范围是:-(2n-1-1)~+(2n-1-1),其中n为机器字长。则:8位二进制原码表示的整数范围是-127~+127。16位二进制原码表示的整数范围是-32767~+32767。

2.反码

对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以外的各位按位取反。记录例子,当机器字长为8位二进制数时:
X=+1011011 [X]原码=01011011   [X]反码=01011011
Y=-1011011 [Y]原码=11011011   [Y]反码=10100100
[+1]反码=00000001    [-1]反码=11111110
[+127]反码=01111111    [-127]反码=10000000

反码表示的整数范围与原码相同。

3.补码

正数的补码与其原码相同,负数的补码为其反码在最低位加1。记录几个例子:

(1) X=+1011011 (2) Y=-1011011
(1) 根据定义有: [X]原码=01011011        [X]补码=01011011
(2) 根据定义有: [Y]原码=11011011        [Y]反码=10100100    [Y]补码=10100101
补码表示的整数范围是-2n-1~+(2n-1-1),其中n为机器字长。则:8位二进制补码表示的整数范围是-128~+127(-128 表示为10000000,无对应的原码和反码)。16位二进制补码表示的整数范围是-32768~+32767。当运算结果超出这个范围时,就不能正确表示数了,此时称为溢出。


最后记录一下程序员宝典上的这道题目:

有两个变量a和b,不用if,?:,switch或者其他判断语句,找出两个数中比较大的。

其中有一个方案是:

int c = a - b;
char *strs[2] = {"a Large", "b Large"};
c = unsigned(c) >> (sizeof(int) * 8 - 1);

 这里的思路就是计算a-b,然后判断c的符号位是0还是1。是0就代表a大。由于c是有符号整型这时候要右移31位获得符号位,如果此时c是负数那么右移之后左边补的是1,所以最终c的取值不在是0,1。所以需要将c转为无符号整型,这样右移之后左边补的是0,最终c保存的就是1~31位是0,第0位保存的是符号位,所以c的取值要不是0,要不是1。

转载于:https://www.cnblogs.com/Key-Ky/p/4432308.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值