【笔试】原码、反码、补码计算,有符号,无符号

下面只是记录自己的不懂的地方。

在笔试中遇到的问题,才发现这个问题没有搞清楚。

首先介绍 原码,补码,反码。

正数的原,反,补码 相同。
负数:原码就是正数的原码,最高位为1;补码:除符号位取反;补码:反码+1**
比如说 -2的原码:1000 0010,反码:1111 1101 补码:1111 1110。

-1的补码:1111 1111。-128的补码:1000 0000,-128没有原码和反码

为解决原码减法问题,引入反码,但是反码引入了+0和-0的问题。
1-1=0
1 - 1 = 1 + (-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]反 + [1111 1110]反
= [1111 1111]反 = [1000 0000]原
= -0

解决反码的+0和-0问题,引入补码问题。这样-0的表示为-128

(-1) + (-127) = [1000 0001]原 + [1111 1111]原
= [1111 1111]补 + [1000 0001]补
= [1000 0000]补
=-128

类型的范围
char:-128 — 127 一共256个数
unsigned char : 0 —255 一共256
short:-32768—32767
unsigned short:0—65535
int 2147483648~2147483647
unsigned int 0~4294967295

有符号和无符号的计算

当有符号和无符号计算时,有符号会提升成无符号计算。

例题1、

unsigned int a = 12;
int b = -14;
cout <<a+b<<endl;

分析:
12 - 14
= [0000 0000 0000 1100]原 + [1000 0000 0000 1110]原
= [0000 0000 0000 1100]补 + [1111 1111 1111 0010]补
= [1111 1111 1111 1110]补
但是结果是无符号的,在计算机中数字存储的是补码存放的。
所以将上面的数字看出无符号的,[1111 1111 1111 1110]看做无符号的整数,
正好为unsigned int 的最大范围-1:4294967294

例题2、

    int a = -25;
    a = a >> 2;
    cout << a << endl;

a的原码:1000 0000 0001 1001
补码: 1111 1111 1110 0111
向右移2位:[1111 1111 1111 1001]补码
原码:【1000 0000 0000 0111】=-7。

例题3、

union test
{
    char m[4];
    int a;
};
test t;
t.a = 0x00ffffaa;
printf("%d\n", t.m[0]);

小端存储:低位存放到低地址处。

联合体:char m[4]:从m[0],m[1],m[2],m[3];也是低地址到高地址

所以m[0]存放的是低位aa
计算机中存储的补码:1010 1010
原码:1101 0110 为-86。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值