原码,补码和反码及整型溢出

一.原码,补码和反码
计算机只能存储0和1,因此在计算机中,数字是采用二进制表示的。
例如看看计算机是如何存储数字5的:

5在内存中的为:0x00000005(采用的16进制表示)
而转换为二进制为:0000 0000 0000 0000 0000 0000 0000 0101 共32位,这个称为5的原码

而计算机CPU中,是只能进行加法功能的,减法的计算都是形如“2+(-5)”的形式进行的

下面我们看看计算机是如何存储-5的:

方法为:计算机要对数字”5“取反,再加1
对5取反为:1111 1111 1111 1111 1111 1111 1111 1010
再加1为:1111 1111 1111 1111 1111 1111 1111 1011  在内存中(16进制)即为0xfffffffb,称为补码

对于补码:1.正数的补码就是其本身
         2.负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后加1
         3.负数在内存中就是以补码形式存储的

对-5加2得 1111 1111 1111 1111 1111 1111 1111 1011(-5)
       + 0000 0000 0000 0000 0000 0000 0000 0010(2)
       -----------------------------------------
         1111 1111 1111 1111 1111 1111 1111 1101  在内存中(16进制)即为0xfffffffd

         注:1.1111=1*(2^3)+1*(2^2)+1*(2^1)+1*(2^0)=15 在16进制中为'f'; 1101同理,为13,       即16进制中的‘d’
             2. 对于有符号常数,最高位就是符号位,符号位是1,就是负数,如果为0就是正数。
                负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后加1。

但是需要注意的是,在考研的时候一般通过8位表示,比如-5 就是1111 1011来表示

反码:反码就是在计算机中数的机器码表示,对于单个数字而言,正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。

二.符号数和无符号数的运算

我们再看下面一个例子:
两个无符号数字 unsigned int a=134;unsigned int b=246; unsigned x=a-b;
那么此时该如何计算呢?
对于134的2进制:1000 0110
而对于246,虽然是无符号数字,但是在计算的时候仍然可以取反加1来计算
246:1111 0110 取反加一后为:0000 1010
134-246=1000 0110+0000 1010=1001 0000=90H 这里不用管他是负数啥的,可以理解为取了绝对值

那么再看这样一个操作:unsigned int a=134; int m=a;
那此时的m的值是多少呢?
因为a是一个无符号数变成了一个有符号数
所以a=134:1000 0110 的最高位就变成了一个符号位,所以m是一个负数
求m就要让a取反加1,得m的绝对值。
a取反加1的结果位(1)111 1010=122,所以m就是-122

符号数的加减和无符号数的加减用的是同一个加法器

三.逻辑移位和算数移位
逻辑移位:左移和右移空位都补0,所有数字参与计算
算数位移:符号位不移动,右移空位补符号位,左移空位补0

四.整型溢出

由上面的知识可知,因为有符号整型数据和无符号整型数据,由于他们的最高位代表的意义不同,所以两者能代表的数字的范围不同,
超出范围会发生溢出现象,导致计算错误。

我们看下面一个例子:

#include<stdio.h>
int main()
{
    short a=32767;
    short b=0;
    b=a+1;
    printf("%d",b);
    return 0;
}
运行这个代码会发现,b=a+1,输出的结果变成了-32768,从一个正数变成了负数。
这是因为32767对应的内存位0x7fff,加1后变成了0x8000,最高位由0变成了1,因此变成了一个负数。
而运行这个代码:

#include<stdio.h>
int main()
{
    unsigned a=32767;
    unsigned b=0;
    b=a+1;
    printf("%d",b);
    return 0;
}
输出结果为32768,此时就是正确的,因为无符号整型数最高位不代表正负。

判断带符号整型数加/减溢出:

符号位和数据高位(即除了符号位的最高位)没有同时进位或者没进位,就会发生溢出

考研会考8位的,也就是一个字节的整型数大小,对于一个字节的有符号类型的数值范围是-128~127,而无符号数则是0~255

(因为对于short来说,是16位,2字节,所以是-2^(16-1)~2^(16-1)-1;变成了8位,1字节,就是把16变成了8)

(因为对于int 来说,是32位,4字节,一样要除以指数要除以4)

(个人笔记,如有错误,感谢指正)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值