嗨嗨嗨
这里是喜欢睡觉的懒狗一只,随缘更新,原因嘛,可能和我完美主义有关,我希望有一天能好吧。如果内容对你有帮助的话,记得一键三联!你的支持会让我更有动力更新下去(虽然感觉也没人看,但还是放一段话好了)
一、整数在内存中的存储
所有数字在内存中是以二进制的形式保存的,懂得都懂,因为计算机只能读懂二进制的东西。神说要保存一个数字,于是就有了原码、反码、补码,甚至移码。但是数字在内存中是以补码的形式保存的。你可能想问,补码是什么东东?上面那四个码又是什么东东?互相有什么关联吗?不对,你不是要谈论整数在内存中是怎么存储的吗?
原码,就是计算机用来表示二进制的一种方法,如果要保存int类型,就要用32位二进制数字来保存,这也是int用四个字节来保存的原因,它的表示范围很大的,由于第一位是用来判断数字正负的(0为正,1为负),所以就少了一位,实际上int 能表示的数字范围为:(-2^31,2^31-1),这是有符号的,而无符号的就为:(0,2^32-1).这个码是不能直接参与运算的。必须转换为补码才行。
反码,就是原码除了符号位不变之外其他位都按位取反后的一个二进制数字,这里不再赘述
补码,就是反码+1后得到的二进制数字。
敲黑板,这里是重点,正整数的原码反码补码是相同的,负数的原码才需要上面这些转换来得到补码。
你现在也很好奇为什么内存当中是以补码形式来存的,我把这段内容给你看看
在计算机系统中,数值⼀律⽤补码来表⽰和存储。
原因在于,使⽤补码,可以将符号位和数值域统⼀处理;
同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是
相同的,不需要额外的硬件电路。
阅读到这里,如果你已经知道这些已经很了不得了。
如果存储一个大数字,而内存又是以字节为单位来存储数据的。就是在内存中申请一份空间存储数字时,内存肯定不是直接啪一下就把数字存进去了,而是一个字节一个字节地存,是有存储顺序的,接下来就是新的概念了。
大小端
⼤端(存储)模式:是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。(keil)
⼩端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存在内存的⾼地址处。(x86环境)
如果应付笔试的话,记住上面的内容就够了。
二、浮点数在内存中的存储
浮点数在内存中的存储和整数是不一样的,拿%d打印浮点型会得不到想要的结果的,同理拿%f打印整数也不会打印出来想要的结果。
这个浮点数的存储啊,和整型唯一相同的点在于它最高位也是符号位,但是后面的位数就不全是用来表示数值的了,对于32位浮点型(float型),首位我们称为S,后面8位称之为E,再往后23位才是存储数值的。我们把他们称之为M,对于任何的浮点数,我们都可以将他们写为
V= (-1)^(S)*M*2^E,
你可能也很懵逼,这是什么玩意啊?别急,听我慢慢讲来
首先S是符号位,如果是正数,那S=0,如果为负数,那S=1
其次M表示有效数字,数值取值范围[1,2)
最后E表示指数,是无符号整型。
举个例子,比如我们想存7.625进去,那第一步我们先判断它是个正数,这样,S就等于0了,然后就是我们先看整数部位7,它二进制可以表示为1111,后面的0.625要怎么表示呢?首先,111每位数字的权重是2^3,2^2,2^1,2^0,那往后的数字权重就应该是负数了,于是我们可以知道2^-1=0.5,2^-2=0.125,所以我们把7.625全部转为二进制后,它可以表示为:1111.11,小数点往前挪三位后表示为1.11111*10^3,我们又得到了E=3,接下来就是M了,它变成111111了,用二进制表示这个数:
0 00000011 1111100 00000000 0000000
S E M
对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。
1.存的过程
很明显,M=1.xxxxxx,我们可以看出来M的整数部分肯定一直为1,于是就在M部分我们不会保存1,只保存小数部分。如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE?754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。⽐如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001
2.取的过程
①E不为全0,不为全1
指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第⼀位的1。
②E为全0
表示很小的数字
③E为全1
表示很大的数字,±∞