CMU-15213-bits-ints-part1总结

该文章为作者自学CMU 15213 课程的自我总结,希望也可以帮到你,学习资源为b站加cmu课程主页,配套书籍为CSAPP,使用的程序语言为C
如果觉得有帮到你,请点赞收藏,谢谢!!!

概括

首先第一二节课是在回顾一些基本概念,如bit和byte,其次以bit的角度去看待我们如何存储int类型,如何在bit层次上进行移位、裁切、拓展等操作,以及计算机内部如何实现乘除操作。

bits

计算机所有的数据都是有bit组成,也就是逻辑上的01和实际电路显示的高低电平,计算机通过不同的方式去解读bit所代表的内容,然后呈现出如今所看到的UI、网页等。使用01最重要的原因是,电路易实现,且能做到较低的出错率,如果使用10进制,那么就需要在电平上区分十个等级,但这样电压一旦有波动就会导致识别出错,而简单的01电平是最佳的实现方法,0电平意味着几乎没有电压或者只有一点,而1电平则代表超过一定阈值的电压,这样简单的两分出错率比较低,当然从信息论的角度来看,就意味着1bit所承载的信息量不高,需要大量的bit才能显示所需要的信息。

正因为计算机中所有的数据都有bit组成,这就包括了数字,生活常用的是十进制的数字,那么我们就需要从十进制转换到二进制,首先将一个十进制数除2,取商数不断继续除2,记录余数,最后一次除2得到的余数为二进制最高位,第一次除2得到的为二进制数最低位,按这样的顺序排列余数,得到的就是十进制数字转换后得到的二进制数。

byte

每一个字节就是8个bit,每一个bit可以表示01,组合后一共可以代表256个不同的东西,但是但数据比较大的时候,用二进制表示就会显得数据非常的长,不直观,更常用的表示方法,我们使用16进制表示。根据16是2的四次方,因此,4位二进制就可以表达一个十六进制,因此二进制和十六进制的转换十分容易。但对于十六进制数,我们不是使用1-16来表达,这样的话就会出现歧义,如116是1-16还是11-6的混淆,因此我们使用0-9和A-F表示十六进制中的0-15。

布尔代数

我们有了二进制数,但是我们如何对二进制数进行运算呢?计算机使用的是boolean代数,也就是离散数学和数字电路设计的与、或、非和异或。
与(And):只有双方都是1的时候才能取到1,其他都为0
或(or):其中一方为1的时候就可以得到1,其他都为0
异或(xor、Exclusive or):只有其中一方为1才能得到1,与或的区别为同时为1的时候,得到的是0
非(Not):一个数是0经过非就是1,反之同理
布尔代数更多的时候是对于集合做的运算,如如果假设使用w位的bit代表一个集合,每一位bit则代表一个事物,可以代表w个事物,那么在一个集合中,如果某一位位1,代表集合中包含这个事物,这样的话根据我们的与或非定义,我们就可以很轻松的求得集合的交集(与)、并集(或)、补集(非)和非并集(异或)

C逻辑中的&&、||、!

在c语言中的与或非和布尔代数不一样,只有0才是false、所有非0的值都为true,返回值就只有0和1,如!0x40得到的就是0x00,!0x00得到0x01。

tips: 在使用指针的时候可以使用 p&&*p来判断指针非空且有内容。

移位操作

左移操作符:<< 。左移操作后,抛弃掉所有因左移操作在高位溢出的数,并在低位处填补上0
逻辑右移:>>。抛弃掉所有右移在低位溢出的数,并且在高位直接补0.
算术右移:>>。抛弃掉所有右移在低位溢出的数,并且根据原先最高位的数字来填补高位。这作用体现在有符号数中的负数操作。

有符号数和无符号数

C使用的是二进制补码的方式去体现有符号数,规定了最高位为符号位,0代表正数,1代表负数。我们假设一个8位的二进制数,如果是无符号数,则每一位都代表2的次方数,如第一位代表2的0次方也就是1,最高位代表2的7也就是128,但是在二进制补码中,最高位代表的是-128,余下的七位仍代表原来的数,因此举例10,10的表示为00001010,从每一位的角度看,就是2的3次方加2的1次方,对于-10,则表示为11110110,也就是-128+64+32+16+4+2=-10,最高位的1代表1*-128,第七位的1代表1*64,依次类推。
当然我们有更简单的方法记忆,就是我们知道原码,如知道10的原码为00001010,那么-10就是原码的取反加一,得到的也是11110110,之所以取反加一是因为当时用二进制补码的方式去表示一个数的时候,我们以8为二进制数举例,最小的数是-128,最大的数为127,在二进制上的表现,这两个数分别为10000000和01111111,可以看到如果我们把所有的二进制数都排列出来,整个表是上下对称的十进制数,而因为0的关系,正数最大值为127,负数最大值为-1,也就是11111111,最小值为-128,0的取反得到的是-1,127取反得到的是-128,因此取反加一的原因就在于10的二进制码取反后,根据上下对称关系,我们得到的是-11而不是-10,因此我们需要再加一才得到我们需要的-10。

有符号数和无符号数的转换

对于无符号数和有符号数的转换,可以看到就是最高位的一个变化,从最大的一个负数权重变为最大的一个正数权重,在转换的时候需要注意这个权重的切换,就可以准确地切换权重,而对于C语言,无符号数和有符号数一起进行运算,有符号数会隐形切换为无符号数,因此在使用过程中必须要小心隐形切换带来的影响。

拓展和截断

对于有符号数和无符号数的拓展,都只需要把最高位的bit复制到拓展的所有位上即可。对于无符号数和有符号数的截断则是直接的将所需截断的长度抛弃,但注意,有符号数截断后所代表的值有可能发生变化,如-6为11010,截断后为1010,所代表的值没有变化,但-10为10110截断后为0110,值发生了变化。对于截断我们可以看作是一种模的运算,还是以-6和-10为例子,-6 mod 16 = 26u mod 16 = 10u = -6,-10 mod 16 = 22U mod 16 = 6U =0110。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值