float类型在内存中的存储

来源:互联网 发布:巨人网络官网 编辑:程序博客网 时间:2024/05/01 14:51

首先还是看一道题目:

<span style="font-size:18px;">#include "stdafx.h"#include <iostream>#include <string>using namespace std;int _tmain(int argc, _TCHAR* argv[]){float a = 1.0f;cout << (int)a << endl;                                    //结果为1cout<< &a <<endl;                                          //结果为0023F924(16进制表示的a变量的存储地址)cout<< (int)&a <<endl;                                     //结果为2357540(上述16进制地址的10进制表示)cout<< (int&)a << endl;                                    //结果为1065353216(这是啥)cout<< boolalpha << ((int)a == (int&)a) << endl;           //结果为falsefloat b = 0.0f;cout << (int)b <<endl;                                     //结果为0cout << &b << endl;                                        //0023F918(16进制表示的变量的存储地址)cout << (int&)b <<endl;                                    //结果为0cout << boolalpha << ((int)b == (int&)b) << endl;          //结果为falsereturn 0;}</span>
对于上述的测试结果,&a和(int)a 的输出结果很好理解,但是(int&)a的结果似乎不太明白。

1065353216的值实际为1.0f浮点数类型再内存中表示的二进制数直接转化成10进制的数表示的值:

a = 1.0f在内存中的表示(二进制):00111111 10000000 00000000 00000000 (浮点型数的二进制的表示请看下文),其中最高位1表示符号,剩下位数的十进制数即为1065353216。

也就是说,(int&)a是将a的引用强制转换为整型,意思是a所在的内存,本来定义的时候为float类型,并初始为1.0f,
但现在我要按int类型解释这段内存(也就是说a所在的内存地址中的数据本来是按float型存储表示的,你非要按int型来解释不可)。

而(int)a是将浮点数类型a先进行了强制类型转换成了int型值,再输出结果,因此结果即为1.



下面介绍下浮点数在二进制中的表示方法( C/C++浮点数在内存中的存储方式):

任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100。则在Intel CPU架构的系统中,存放方式为  10000100(低地址单元) 00000100(高地址单元),因为Intel CPU的架构是小端模式。但是对于浮点数在内存是如何存储的?目前所有的C/C++编译器都是采用IEEE所制定的标准浮点格式,即二进制科学表示法。

       在二进制科学表示法中,S=M*2^N 主要由三部分构成:符号位+阶码(N)+尾数(M)。对于float型数据,其二进制有32位,其中符号位1位,阶码8位,尾数23位;对于double型数据,其二进制为64位,符号位1位,阶码11位,尾数52位。

                31        30-23       22-0

float       符号位     阶码        尾数

                63        62-52       51-0

double    符号位     阶码        尾数

符号位:0表示正,1表示负

阶码:这里阶码采用移码表示,对于float型数据其规定偏置量为127,阶码有正有负,对于8位二进制,则其表示范围为-128-127,double型规定为1023,其表示范围为-1024-1023。比如对于float型数据,若阶码的真实值为2,则加上127后为129,其阶码表示形式为10000010

尾数:有效数字位,即部分二进制位(小数点后面的二进制位),因为规定M的整数部分恒为1,所以这个1就不进行存储了。

下面举例说明:

float型数据125.5转换为标准浮点格式

125二进制表示形式为1111101,小数部分表示为二进制为 1,则125.5二进制表示为1111101.1,由于规定尾数的整数部分恒为1,则表示为1.1111011*2^6,阶码为6,加上127为133,则表示为10000101,而对于尾数将整数部分1去掉,为1111011,在其后面补0使其位数达到23位,则为11110110000000000000000

则其二进制表示形式为

0 10000101 11110110000000000000000,则在内存中存放方式为:

00000000   低地址

00000000

11111011

01000010   高地址

而反过来若要根据二进制形式求算浮点数如0 10000101 11110110000000000000000

由于符号为为0,则为正数。阶码为133-127=6,尾数为11110110000000000000000,则其真实尾数为1.1111011。所以其大小为

1.1111011*2^6,将小数点右移6位,得到1111101.1,而1111101的十进制为125,0.1的十进制为1*2^(-1)=0.5,所以其大小为125.5。

同理若将float型数据0.5转换为二进制形式

0.5的二进制形式为0.1,由于规定正数部分必须为1,将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为

0 01111110 00000000000000000000000

由上分析可知float型数据最大表示范围为1.11111111111111111111111*2^127=3.4*10^38

对于double型数据情况类似,只不过其阶码为11位,偏置量为1023,尾数为52位。

至此,就不难得出float  a = 1.0f的二进制存储值了,阶码值为0 ,偏移127,得到的二进制位为011111111,最高位为符号位0,后面的位数由于是0,因此直接补0,补齐23位。

得出结果:0 01111111 00000000000000000000000。

<span style="font-size:18px;">//测试程序#include <stdio.h>using namespace std;int main(int argc, char *argv[]){    float a=125.5;    char *p=(char *)&a;    printf("%d\n",*p);          //输出结果为0    printf("%d\n",*(p+1));      //输出结果为0    printf("%d\n",*(p+2));      //输出结果为-5    printf("%d\n",*(p+3));      //输出结果为66    return 0;}</span>
125.5在内存中的表示为:125.5转化为二进制:1111101.1,变为整数位为1,位1.1111011 * 2 ^6,阶码为6,偏移127等于133,二进制表示为10000101。再计算尾数,将整数部分的1去掉得1111011,其余的在后面补0,补足23位。因此二进制表示为:0 10000101 11110110000000000000000。


在上面已经知道float型125.5在内存中存放方式为:

00000000   低地址

00000000

11111011

01000010   高地址

因此对于p和p+1指向的单元,其中存储的二进制数表示的十进制整数为0;

而对于p+2指向的单元,由于为char型指针,为带符号的数据类型,因此11111011,符号位为1,则为负数,由于在内存中二进制是以补码存储的,所以其真值为-5.

对于p+3指向的单元,01000010,为正数,则其大小为66。上面程序输出结果验证了其正确性。








0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 模拟工业装置没有数据验证怎么办 民办学校的指标生学费怎么办 孩子上初中后成绩不好怎么办 孩子考最后一名怎么办 数学大题不会做怎么办 小学六年级数学考30分怎么办 六年级数学考了30分怎么办 数学考了30分怎么办 没有给直接领导报到怎么办 小学二年级成绩不好怎么办 初中孩子上课注意力不集中怎么办 学生打架家长争吵老师怎么办 我和我老婆感情危机怎么办 数学作业做得慢怎么办 待转弯区变红灯怎么办 大班健康发生火灾怎么办教案 数字化审图图纸提交不了怎么办 监狱建筑师没电了怎么办 ios短信提示不弹出怎么办 ie游览器图标删了怎么办 电脑上ie卸载了怎么办 打开cad浏览器闪退怎么办 dnf进游戏闪退怎么办 苹果8出现闪退怎么办 手机浏览器老是自动打开软件怎么办 打开手机浏览器为什么是英文怎么办 ie浏览器删除掉了怎么办 手机360浏览器卸载不掉怎么办 大学素质拓展学分不够怎么办 专升本学分不够怎么办 电脑连接无线网络网关禁用怎么办 背部毛孔粗大有黑头怎么办 毛孔变粗大长痘怎么办 皮肤粗糙暗黄毛孔大怎么办 毛孔粗大还有痘印怎么办 高一的不爱上数学怎么办 监狱系统需要体测怀孕怎么办 货运从业资格证年审过期了怎么办 科三线路记不住怎么办? 汽车大灯里面起雾水怎么办 二级重伤对方法庭拒绝赔偿怎么办?