深入谈谈整型、浮点型在内存中的存储方式

    xiaoxiao2021-12-14  19

    ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼

    分享一个大神朋友的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!点击浏览教程。写得特别用心喔~

    →→→→→→大神朋友简介:从事十几年人工智能研究,麻省理工博士学位,目前在百度继续进行着人工智能的研究。。。▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲

    浅入了解:

    整数:请点我~

    小数:请点我~

     

     

    测试环境:VC6.0编译器(int型为4Byte)

     

    先简介一下大小端模式

     

    大端模式:Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端小端模式:Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端

     

    我们常用的x86系列cpu,就是小端模式存储方式的……

    深入了解大小端请点我!

    一、正整型

     

    正整型,没什么好说的,就是补码存储方式,正数的补码和原码相同,即先转换为二进制,然后高位扩展0,一直填充至32位……比如:5这个数的存储方式如下先转换为二进制:101因为只有3位,所以前面填充29个0,即 00000000 00000000 00000000 00000101二、负整型负整型,跟正整型一样,也是补码存储方式,不过负数的补码计算方式是取绝对值的二进制,按位取反再加1比如:-5这个数先取绝对值,即5,即 00000000 00000000 00000000 00000101然后按位取反:11111111 11111111 11111111 11111010再加1:即 11111111 11111111 11111111 11111011

     

     

    三、正浮点型

    浮点型中有两种,一种是4Byte的float型,一种是8Byte的double型,这两种计算方式都一致,只是有点点区别1、float型:float型是遵循IEEE R32.24规范,即1位符号位、8位阶码、23位尾数具体计算方式是先用科学计数法表示出该数的二进制,然后计算出阶码值,最后把尾数 补足23位,依此存储比如125.5这个数先看整数部分,125表示成二进制是1111101,(整数转换二进制是除二取余)再看小数部分,0.5表示成二进制是0.1,(小数转换二进制是乘二取整)所以125.5用二进制表示就是1111101.1,转换成科学计数法就是1.1111011 x 2^6(阶数为6)但是这里的阶码是用移码的形式表示,float型的偏置量是127,于是6+127=133,即10000101这里前面的9位就出来了,因为是正数,所以符号位为0,阶码为10000101后面的尾数就是1111011,在后面补0,凑齐23位,即 1111011 00000000 00000000(因为科学计数法的整数部分总是为1,所以,这个1不用存储)所以125.5的存储方式为 0 10000101 11110110000000000000000即: 01000010 11111011 00000000 000000002、double型double型跟float型计算方式类似,不过区别在于double型遵循IEEE R64.53规范a、double的符号位是1位,阶码为11位,尾数为52位b、double的偏置量是1023,而float是127四、负浮点型和上面一样,不过就是符号位用1表示,就这点小区别五、验证方式有两种验证方式,一种是用联合体的方法、一种是强制类型转换方法1、联合体法:可以定义一个联合体,比如union data{float a;char array[4];};那么可以对a赋值,然后依次输出数组array的各个元素,这样就可以验证2、强制类型转换法:float a;char *p=(char *)&a;这样,将a的地址强制转换为指向字符类型之后,赋值给指针p,后续再依次输出*p、*(p+1)、*(p+2)、*(p+3)的值,也可以进行验证

    例:

     

    #include int main(int argc, char *argv[]) { float a= 0.5; char *p = (char *)&a; printf("%d.\n",*(p+0)); printf("%d.\n",*(p+1)); printf("%d.\n",*(p+2)); printf("%d.\n",*(p+3)); return 0; } int main(int argc, char *argv[]) { float a= 0.5; char *p = (char *)&a; printf("%d.\n",*(p+0)); printf("%d.\n",*(p+1)); printf("%d.\n",*(p+2)); printf("%d.\n",*(p+3)); return 0; }

     

     

     

    分析:0.5的二进制形式为0.1,由于规定正数部分必须为1,将小数点右移1位,则为1.0*2^(-1);

    0 01111110 00000000000000000000000

    符号位 阶码转化为二进制(-1+127) 小数部分

    裁剪:

    00111111

    00000000

    00000000

    00000000

    结果:

     

     

     

     

     

     

     

     

     

     

    转载请注明原文地址: https://ju.6miu.com/read-963496.html

    最新回复(0)