float数据在计算机内存中的存储方法

***************************************************

更多精彩,欢迎进入:http://shop115376623.taobao.com

***************************************************


浮点型变量在计算机内存中占用4字节(Byte),即32-bit。遵循IEEE-754格式标准。


一个浮点数由2部分组成:底数m指数e
  ±mantissa × 2exponent
(注意,公式中的mantissa 和 exponent使用二进制表示)
底数部分 使用2进制数来表示此浮点数的实际值。
指数部分 占用8-bit的二进制数,可表示数值范围为0-255。

但是指数应可正可负,所以IEEE规定,此处算出的次方须减去127才是真正的指数。所以float的指数可从 -126到128.

底数部分实际是占用24-bit的一个值,由于其最高位始终为 1 ,所以最高位省去不存储,在存储中只有23-bit。

到目前为止, 底数部分 23位 加上指数部分 8位 使用了31位。那么前面说过,float是占用4个字节即32-bit,那么还有一位是干嘛用的呢? 还有一位,其实就是4字节中的最高位,用来指示浮点数的正负,当最高位是1时,为负数,最高位是0时,为正数。

浮点数在4字节中的存放:
浮点数据就是按下表的格式存储在4个字节中:
Address+0 Address+1 Address+2 Address+3
Contents SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
 S: 表示浮点数正负,1为负数,0为正数


E: 指数加上127后的值的二进制数
M: 24-bit的底数(只存储23-bit)

主意:这里有个特例,浮点数 为0时,指数和底数都为0,但此前的公式不成立。

因为2的0次方为1,所以,0是个特例。当然,这个特例也不用认为去干扰,编译器会自动去识别。


通过上面的格式,我们下面举例看下-12.5在计算机中存储的具体数据:
Address+0 Address+1 Address+2 Address+3
Contents 0xC1 0x48 0x00 0x00
 接下来我们验证下上面的数据表示的到底是不是-12.5,从而也看下它的转换过程。
由于浮点数不是以直接格式存储,他有几部分组成,所以要转换浮点数,首先要把各部分的值分离出来。

Address+0 Address+1 Address+2 Address+3
格式 SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
二进制 11000001 01001000 00000000 00000000
16进制 C1 48 00 00


可见:
S: 为1,是个负数。
E:为 10000010 转为10进制为130,130-127=3,即实际指数部分为3.
M:为 10010000000000000000000。 这里,在底数左边省略存储了一个1,使用 实际底数表示为 1.10010000000000000000000 
到此,我们吧三个部分的值都拎出来了,现在,我们通过指数部分E的值来调整底数部分M的值。

调整方法为:如果指数E为负数,底数的小数点向左移,如果指数E为正数,底数的小数点向右移。小数点移动的位数由指数E的绝对值决定。
这里,E为正3,使用向右移3为即得:
1100.10000000000000000000
至次,这个结果就是12.5的二进制浮点数,将他换算成10进制数就看到12.5了,

如何转换,看下面:

小数点左边的1100 表示为 (1 × 23) + (1 × 22) + (0 × 21) + (0 × 20), 其结果为 12 。
小数点右边的 .100… 表示为 (1 × 2-1) + (0 × 2-2) + (0 × 2-3) + ... ,其结果为.5 。
以上二值的和为12.5, 由于S 为1,使用为负数,即-12.5 。
所以,16进制 0XC1480000 是浮点数 -12.5 。

上面是如何将计算机存储中的二进制数如何转换成实际浮点数,下面看下如何将一浮点数装换成计算机存储格式中的二进制数。
举例将17.625换算成 float型。
首先,将17.625换算成二进制位:10001.101 ( 0.625 = 0.5+0.125, 0.5即 1/2, 0.125即 1/8 如果不会将小数部分转换成二进制,请参考其他书籍。)

再将 10001.101 向右移,直到小数点前只剩一位 成了 1.0001101 x 2的4次方(因为右移了4位)。此时 我们的底数M和指数E就出来了:
底数部分M,因为小数点前必为1,所以IEEE规定只记录小数点后的就好,所以此处底数为 0001101 。
指数部分E,实际为4,但须加上127,固为131,即二进制数 10000011 
符号部分S,由于是正数,所以S为0.
综上所述,17.625的 float 存储格式就是:
0 10000011 00011010000000000000000
转换成16进制:0x41 8D 00 00
所以,一看,还是占用了4个字节。

十进制小数→→→→→二进制小数 方法:“乘2取整”

对十进制小数乘2得到的整数部分和小数部分,整数部分既是相应的二进制数码,再用2乘小数部分(之前乘后得到新的小数部分),又得到整数和小数部分.
如此不断重复,直到小数部分为0或达到精度要求为止.第一次所得到为最高位,最后一次得到为最低位
如:0.25的二进制
0.25*2=0.5  取整是0
0.5*2=1.0    取整是1
即0.25的二进制为 0.01 ( 第一次所得到为最高位,最后一次得到为最低位)

0.8125的二进制

0.8125*2=1.625   取整是1

0.625*2=1.25     取整是1

0.25*2=0.5       取整是0

0.5*2=1.0        取整是1

即0.8125的二进制是0.1101(第一次所得到为最高位,最后一次得到为最低位)


《代码优化:有效使用内存》,发现里面提到了两种方法:
1
#pragma pack(push)
#pragma pack(1)
struct struct1
{
    int i;
    short j;
    char c;
};
#pragma pack(pop)

2
修改编译指令的参数,来禁止内存对齐:
VC++             /Zn1(VS2005下,右击项目-属性-配置属性-C/C++-代码生成-结构成员对齐-“1字节(/Zn1):”(即禁止内存对齐),默认是使用默认值,即按照结构中占用空间最大的成员进行对齐。的size进行对齐。
Borland C++  /-a1

2是对整个项目禁用内存对齐,而法1可以针对特定的结构禁用内存对齐,其提供了更大的灵活性.



另外,该书中还提到:
char
不对齐;
short
沿偶地址对齐;
int/float
沿取值为4的倍数的地址对齐。
double
沿取值为8的倍数的地址对齐


补充:数据的手工对齐:

char *p;
int temp = align_power-1;
p=(char*)malloc(need_size + temp;
p=(char*)malloc(((int)p+temp)&temp);//修改了p,所以释放p前记得要归位.注:align_power是所需要的对齐幂,char*(也可以为int*)是指针类型。另外,释放p之前记得让其指向所申请的内存的首地址上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458901.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Geometric Shapes - POJ 3449(多边形相交)

题目大意:给一些几何图形的编号,求出来这些图形都和那些相交。分析:输入的正方形对角线上的两个点,所以需要求出来另外两个点,公式是:x2:(x1x3y3-y1)/2; y2:(y1y3x1-x3)/2;x4:(x1x3-y3y1)/2; y4:(y1y3-x1x3…

更新10_linux,时隔十年,QQ更新了Linux版本

昨天1024程序员节,QQ悄悄地更新了QQ for Linux,也许是给各位一个惊喜吧。官网及其的简陋。和一个Word文档似的。十年一更,有网友称,瞬间回到QQ2006,确实界面功能有些落后,相信QQ可以跟上潮流的,…

[渗透测试]扫目录,Sqlmap利用均超时,利用dirb扫描

今天碰到一个网友传来的Webshell地址,问我对方如何取得webshell。 网站为阿里云服务器,存在明显的注入漏洞,但是任何语句都会令网页报错,sqlmap一直超时,御剑扫描目录1个线程也会导致被屏蔽IP。 经一学长提点&#xff…

x = x+1,x+=1,x++那个的执行效率高

*************************************************** 更多精彩,欢迎进入:http://shop115376623.taobao.com *************************************************** x x1的效率最低 1)读取右边x的地址 2)执行x13)读…

修正线性单元(Rectified linear unit,ReLU)

修正线性单元(Rectified linear unit,ReLU) Rectified linear unit 在神经网络中,常用到的激活函数有sigmoid函数f(x)11exp(−x)、双曲正切函数f(x)tanh(x),今天要说的是另外一种activation function,recti…

C语言综合期末作业,内蒙古农业大学2010年期末c语言综合作业.doc

内蒙古农业大学2010年期末c语言综合作业综合练习作业#includeint main(void){int choice,i;void shuai();void ge();void wang();void bing();for(i1;i<5;i){printf("[1]统计字符个数\n");printf("[2]判断素数\n");printf("[3]求斐波那契数列\n&qu…

链表创建、逆置、删除详解

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 对链表的理解&#xff1a;http://www.nowamagic.net/librarys/veda/detail/2220 #inc…

python与shell的3种交互方式介绍

【目录】 1.os.system(cmd) 2.os.popen(cmd) 3.利用subprocess模块 4.subprocessor模块进阶 【概述】 考虑这样一个问题&#xff0c;有hello.py脚本&#xff0c;输出”hello, world!”&#xff1b;有testinput.py脚本&#xff0c;等待用户输入&#xff0c;然后打印用户输入的数…

C语言里if语句变量作为判断条件,C语言教学(九-上)if else判断语句

原标题&#xff1a;C语言教学(九-上)if else判断语句今天讲if else判断语句&#xff0c;简单理解就是进行条件判断&#xff0c;如果条件达到则执行if 里或else里的语句。先来看if。if的写法和for差不多,就是不用括号里的两个分号&#xff0c;if (条件) { }&#xff0c;if加括号…

const修饰指针和引用的用法【转贴】

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** const修饰的指针会额外的占内存吗&#xff1f; 仍然是4&#xff0c;不会占额外的…

调整linux系统时区

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 好吧&#xff0c;使用tzselect又靠谱些&#xff0c;使用前把/etc/localtime删除了。 执行上前那个告诉我文件重新了&#xff0c;所以就没有搞了转载于:https://www.cnblogs.com/hark0623/p/4807426.html

stm32c语言设计以及注释,13个基于STM32的经典项目设计实例,全套资料~-嵌入式系统-与非网...

STM32单片机现已火遍大江南北&#xff0c;各种教程资料也是遍布各大网站论坛&#xff0c;可谓一抓一大把&#xff0c;但大部分都差不多。今天总结了几篇电路城上关于STM32 的制作&#xff0c;不能说每篇都是经典&#xff0c;但都是在其他地方找不到的&#xff0c;很有学习参考意…

memcpy,strcpy,strncpy

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** memcpy c和c使用的内存拷贝函数.从源src所指的内存地址的起始位置开始拷贝n个字节…

二维数组联通子数组和最大

题目要求&#xff1a; 返回一个二维整数数组中最大联通子数组的和。输入一个二维整形数组&#xff0c;数组里有正数也有负数。文件输出。思路:和之前的动态规划相识&#xff0c;把二维数组转换为一维数组&#xff0c;先求每一个列的子数组和最大&#xff0c;最后在用正数就加&a…

c语言如何给变量加锁,C语言互斥锁-条件变量实现公共缓存区数据读写

#include char buffer[128];int has_data0;pthread_mutex_t mutex;pthread_cond_t cond;pthread_cond_t cond2;void read_buf(void){do{pthread_mutex_lock(&mutex);//锁定互斥锁if(has_data0){/*阻塞线程,等待另外一个线程发送信号&#xff0c;同时为公共数据区解锁*/pthr…

view-activity跟控件在onkey事件上的传递关系

android 中Activity跟View对于键盘的监听&#xff0c;主要有以下几个方法 //按键按下 public boolean onKeyDown(int keyCode, KeyEvent event) {} //按键弹起 public boolean onKeyUp(int keyCode, KeyEvent event) {} //常按 public boolean onKeyLongPress(int keyCode, Ke…

PMP考试的过与不过

*************************************************** 更多精彩&#xff0c;欢迎进入&#xff1a;http://shop115376623.taobao.com *************************************************** 我在一年多时间里参加了三次PMP考试&#xff0c;前两次都失败&#xff0c;直到第三次才…

JPA一对多循环引用的解决

说是解决&#xff0c;其实不是很完美的解决的&#xff0c;写出来只是想记录一下这个问题或者看一下有没有哪位仁兄会的&#xff0c;能否知道一二。 下面说说出现问题&#xff1a; 问题是这样的&#xff0c;当我查询一个一对多的实体的时候&#xff0c;工具直接就爆了&#xff0…

太原理工大学c语言课程设计报告,[太原理工大学C语言实验报告.doc

[太原理工大学C语言实验报告本科实验报告课程名称&#xff1a; 程序设计技术B实验项目&#xff1a;实验地点&#xff1a; 明向校区软件学院机房专业班级&#xff1a; 学号&#xff1a;学生姓名&#xff1a;指导教师&#xff1a; 呼克佑2014年 12月 日实验名称 实验一 C语言的运…

网页常用动态效果--悬浮广告

关键在于动态获取滚动坐标值 测试滚动事件 $(window).scroll(function(){ console.log($(window).scrolltop()); }) 获取三个高度&#xff1a;窗口高度&#xff0c;盒子高度以及滚动坐标值&#xff0c;将广告盒子设置为绝对定位&#xff0c;当鼠标滚动时&#xff0c;其top值为滚…