计算机基础

一,int类型在内存是如何存储的?

数据类型  占用字节数  取值范围

 int       4byte    -2^31 ~ 2^31-1

unsigned int   4byte    0 ~2^32

1,占用的比特位数

int占用4个字节,每个字节有8个比特位,所以有32个 0-1 的二进制位数。注意:int类型有正负号,unsigned int 没有正负,所以int要用一位来标识正负

2,符号的表示方法

int类型占用的比特位中,左起第一个位(最高位)就是符号位。0表示正数,1表示负数。其余后面31是数值位。

3,数字0怎么表示?

3.1,因为有了正负数,那么就会有 +0 和 -0 。(注意:0有了两种表示:+0,-0)

  +0的表示方法:0000 0000 0000 0000 0000 0000

  -0的表示方法:-2^31

  0就用 +0 的表示方法

3.2,正数部分 2^31-1 ,之所以要减一,就是因为数字0占用了 +0 。负数不需要表示0,-0 就用来表示 -2^31

3.3,int类型的数字 -1 ,在内存中32个比特位上该如何表示?

10000000 00000000 00000001   左边第一个1表示负号,后面31位表示数值部分“1”。---->然而,并不是这样的

二,补码

计算机中的符号数有三种表示方法:原码,反码,补码。这三种表示方法都有符号位和数值位两部分,符号位用 0 表示正,用1 表示负,但是数值的表示,这三个就不相同了。

1,原码

原码是计算机中一种对数字的二进制定点表示方法。原码表示法 最高位位是符号位,正数最高位是0,负数最高位是1。

如何用原码表示一个数?

  -1的表示:10000000 00000000 00000001

  +1的表示:00000000 00000000 00000001

为什么不用原码在内存中表示数值呢?

举个栗子:用8位二进制表示 1 和 -1,然后让这两个数做加法运算

十进制        原码

     1              0000 0001

   -1     1000 0001

结果(原码)   1000 0010

结果(十进制)     -2

这运算结果显然不对。计算机在计算时,加法计算的算法更加便捷,减法会先转为负数,再进行加法运算。所以,原码的符号位不能直接参与运算

总结:原码是有符号数的最简单的编码方式,便于输入输出,但是作为代码加减运算时比较复杂。所以计算机不采用这种编码方式存储符号数。

2,反码

规定:正数的反码和原码相同,负数的反码是对其原码逐位取反,但是符号位除外。

正数 和 +0 ,他们的反码就是原码本身。对于8位二进制的 +1,原码,反码都是 0000 0001

负数 和 -0,符号位不变,其余位数逐位取反(1换成0,0换成1),对于8位二进制的-1,原码:1000 0001,反码:11111 1110

我们再来做一次运算:1+(-1)= 0

十进制        原码        反码

     1              0000 0001    0000 0001

   -1     1000 0001    1111 1110 

结果(反码)              1111 1111   

结果(原码)           1000 0000

结果(十进制)                -0

计算结果是-0,而我们加法运算的结果是0。

问题:由于-0的存在,使得二进制和十进制的互换不是一一对应的关系。这样就需要计算机增加额外的物理硬件配合运算,所以已经抛弃了用反码存储数据

3,补码

3.1,补码就是基于反码的 -0 问题而出现的。补码的计算方法:

正数和 +0 的补码是原码

负数先计算反码,然后反码加1,得到补码

3.2,补码如何换算成原码呢?

如果是正数或 +0 的补码,那么原码就是补码。

如果是负数或-0的的补码,那么先将补码减掉1,得到反码,再将反码取反,得到原码

我们还是以:1+(-1)= 0 为例

十进制        原码        反码        补码

     1              0000 0001    0000 0001    0000 0001

   -1     1000 0001    1111 1110     1111  1111 

结果(补码)                    0000 0000          

结果(反码)                       0000 0000

结果(原码)                     0000 0000        

结果(十进制)                    +0             

 计算结果正确,+0就是数字0的唯一表示

注意:8位二进制补码1000 0000没有对应的反码和原码。   

 所以,int类型在内存中,以补码的形式存储。

三,运算

1,按位与(&)

参加运算的两个数,换算为二进制(0,1),进行与运算:只有当相应位上的数都是1时,才取1,否则该位为0

将10和-10进行按位与(&)运算(需要转成补码后再进行计算):

10      0000 0000 0000 1010

-10       1111  1111  1111  0110    (-10的原码:1000 0000 0000 1010 ,-10的反码:1111 1111 1111 0101 ,-10的补码:1111 1111 1111 0110)

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

按位与结果: 0000 0000 0000 0010

2,按位或(|)

参加运算的两个数,换算位二进制(0,1)后,进行或运算。只要相应位上存在1,那么该位就取1,都不为1,就为0.

将10和-10进行按位与(|)运算(需要转成补码后再进行计算):

10      0000 0000 0000 1010

-10       1111  1111  1111  0110    (-10的原码:1000 0000 0000 1010 ,-10的反码:1111 1111 1111 0101 ,-10的补码:1111 1111 1111 0110)

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

按位或结果:  1111  1111  1111 1110

3,按位异或(^)

参加运算的两个数,换算位二进制(0,1)后,进行异或运算。只要相应位上的数字不相同时,才取1,若相同,就取0

4,取反(~)

参加运算的两个数,换算为二进制(0,1)后,进行取反运算。每个位上都取相反值,1变成0,0变成1。

对10进行取反(~)运算:

0000 0000 0000 1010
---------------------
1111 1111 1111 0101
 

5,左移(<<)

参加运算的两个数,换算为二进制(0,1)后,进行左移运算,用来将一个数的每个二进制位全部向左移动若干位。

对10左移2位(  就相当于在右边加2个0  ):

0000 0000 0000 1010  (10)
--------------------
0000 0000 0010 1000  (40 = 10 * 2^2)

6,右移(>>)

参加运算的两个数,换算为二进制(0、1)后,进行右移运算,用来将一个数各二进制位全部向右移动若干位。

对10右移2位(就相当于在左边加2个0):
0000 0000 0000 1010
--------------------
0000 0000 0000 0010
 
注意哦,除了以后没有小数位的,都是取整。
原文地址:https://www.cnblogs.com/inspred/p/10987936.html