内存中整数和浮点数存储的差异

strongerHuang 2022-05-19 08:36

关注+星标公众,不错过精彩内容

作者 | 夜风

编排 | strongerHuang


为什么我们代码将浮点数、整数进行强制转换,或打印输出时会出精度损失,或出错的情况?


想要搞明白这个问题,就需要了解一下整数、浮点数的存储规则。


浮点数存储规则

根据国际标准IEEE(电气和电子工程协会)规定,任何一个浮点数NUM的二进制数可以写为:


NUM = (-1) ^ S * M * 2 ^ E; (S表示符号,E表示阶乘,M表示有效数字)

①当S为0时,表示一个正数;当S为1时,表示一个负数;

②M表示有效数字,1<= M <2;

③2^E表示指数
比如十进制的3.0,二进制就是0011.0 就可以写成(-1)^ 0 * 1.1 * 2 ^ 1

再比如十进制的-3.0,二进制就是-0011.0 就可以写成(-1)^ 1 * 1.1 * 2 ^ 1

而规定float类型有一个符号位(S),有8个指数位(E),和23个有效数字位(M)

double类型有一个符号位(S),有11个指数位(E),和52个有效数字位(M)

以float类型为例:

IEEE对于(有效数字)M和(指数)E有特殊的规定(以float为例): 
1.因为M的值一定是1<= M <2,所以它绝对可以写成1.xxxxxxx的形式,所以规定M在存储时舍去第一个1,只存储小数点之后的数字。
这样做节省了空间,以float类型为例,就可以保存23位小数信息,加上舍去的1就可以用23位来表示24个有效的信息。

2.对于E(指数)E是一个无符号整数所以E的取值范围为(0~ 255),但是在计数中指数是可以为负的,所以规定在存入E时,在它原本的值上加上中间数(127),在使用时减去中间数(127),这样E的真正取值范围就成了(-127~128)。

对于E还分为三种情况:
①E不全为0,不全为1:
这时就用正常的计算规则,E的真实值就是E的字面值减去127(中间值),M的值要加上最前面的省去的1。
②E全为0
这时指数E等于1-127为真实值,M不在加上舍去的1,而是还原为0.xxxxxxxx小数。这样为了表示0,和一些很小的整数。
所以在进行浮点数与0的比较时,要注意。
③E全为1
当M全为0时,表示±无穷大(取决于符号位);当M不全为1时,表示这数不是一个数(NaN)

测试

代码如下:
void test(void){  float m=134.375;  char *a=(char*)&m;
printf("0x%p:%d\n",a,*a); printf("0x%p:%d\n",a+1,*(a+1) ); printf("0x%p:%d\n",a+2,*(a+2) ); printf("0x%p:%d\n",a+3,*(a+3) );}

代码输出结果:


具体的计算过程如下:


精度损失

我们可以把十进制的小数部分乘以2,取整数部分作为二进制的一位,剩余小数继续乘以2,直至不存在剩余小数为止。
例如0.2可以转换为:
0.2 x 2 = 0.4 0
0.4 x 2 = 0.8 0
0.8 x 2 = 1.6 1
0.6 x 2 = 1.2 1
0.2 x 2 = 0.4 0
0.4 x 2 = 0.8 0
0.8 x 2 = 1.6 1

即:.0011001…
它是一个无限循环的二进制数,这就是为什么十进制小数转换成二进制小数的时候为什么会出现精度损失的情况。

之前前不久给大家分享的《单精度、双精度、多精度和混合精度计算的区别是什么?》可能大家不是很明白,今天看了浮点数的存储规则,你明白了吗?

整数的存储规则

理解了浮点数的存储规则,再理解整数就很简单了。


整数在内存中都是以补码的形式进行存储,整数有正负之分。当需存储有符号数时,用第一位来表示正(0)和负(1)。


正数的反码和补码还是它本身,下面主要讨论下负数的反码和补码。反码是其原码除去最高符号位后其余位按位取反,补码是其反码在加上1 。


测试代码:
void test(void){  int8_t n=-123;  uint8_t *p=(uint8_t *)&n;
printf("%d\n",n); printf("%d\n",*p); }

输出结果:

计算过程如下:


素材来源:
https://blog.csdn.net/u014470361/article/details/79820892

声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。


------------ END ------------



●专栏《嵌入式工具

●专栏《嵌入式开发》

●专栏《Keil教程》

●嵌入式专栏精选教程


关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。




点击“阅读原文”查看更多分享。

strongerHuang 作者黄工,高级嵌入式软件工程师,分享嵌入式软硬件、物联网、单片机、开发工具、电子等内容。
评论
  •     IPC-2581是基于ODB++标准、结合PCB行业特点而指定的PCB加工文件规范。    IPC-2581旨在替代CAM350格式,成为PCB加工行业的新的工业规范。    有一些免费软件,可以查看(不可修改)IPC-2581数据文件。这些软件典型用途是工艺校核。    1. Vu2581        出品:Downstream     
    电子知识打边炉 2025-01-22 11:12 49浏览
  • 现在为止,我们已经完成了Purple Pi OH主板的串口调试和部分配件的连接,接下来,让我们趁热打铁,完成剩余配件的连接!注:配件连接前请断开主板所有供电,避免敏感电路损坏!1.1 耳机接口主板有一路OTMP 标准四节耳机座J6,具备进行音频输出及录音功能,接入耳机后声音将优先从耳机输出,如下图所示:1.21.2 相机接口MIPI CSI 接口如上图所示,支持OV5648 和OV8858 摄像头模组。接入摄像头模组后,使用系统相机软件打开相机拍照和录像,如下图所示:1.3 以太网接口主板有一路
    Industio_触觉智能 2025-01-20 11:04 150浏览
  •  万万没想到!科幻电影中的人形机器人,正在一步步走进我们人类的日常生活中来了。1月17日,乐聚将第100台全尺寸人形机器人交付北汽越野车,再次吹响了人形机器人疯狂进厂打工的号角。无独有尔,银河通用机器人作为一家成立不到两年时间的创业公司,在短短一年多时间内推出革命性的第一代产品Galbot G1,这是一款轮式、双臂、身体可折叠的人形机器人,得到了美团战投、经纬创投、IDG资本等众多投资方的认可。作为一家成立仅仅只有两年多时间的企业,智元机器人也把机器人从梦想带进了现实。2024年8月1
    刘旷 2025-01-21 11:15 390浏览
  • 本文介绍瑞芯微开发板/主板Android配置APK默认开启性能模式方法,开启性能模式后,APK的CPU使用优先级会有所提高。触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。源码修改修改源码根目录下文件device/rockchip/rk3562/package_performance.xml并添加以下内容,注意"+"号为添加内容,"com.tencent.mm"为AP
    Industio_触觉智能 2025-01-17 14:09 164浏览
  • 嘿,咱来聊聊RISC-V MCU技术哈。 这RISC-V MCU技术呢,简单来说就是基于一个叫RISC-V的指令集架构做出的微控制器技术。RISC-V这个啊,2010年的时候,是加州大学伯克利分校的研究团队弄出来的,目的就是想搞个新的、开放的指令集架构,能跟上现代计算的需要。到了2015年,专门成立了个RISC-V基金会,让这个架构更标准,也更好地推广开了。这几年啊,这个RISC-V的生态系统发展得可快了,好多公司和机构都加入了RISC-V International,还推出了不少RISC-V
    丙丁先生 2025-01-21 12:10 111浏览
  • 高速先生成员--黄刚这不马上就要过年了嘛,高速先生就不打算给大家上难度了,整一篇简单但很实用的文章给大伙瞧瞧好了。相信这个标题一出来,尤其对于PCB设计工程师来说,心就立马凉了半截。他们辛辛苦苦进行PCB的过孔设计,高速先生居然说设计多大的过孔他们不关心!另外估计这时候就跳出很多“挑刺”的粉丝了哈,因为翻看很多以往的文章,高速先生都表达了过孔孔径对高速性能的影响是很大的哦!咋滴,今天居然说孔径不关心了?别,别急哈,听高速先生在这篇文章中娓娓道来。首先还是要对各位设计工程师的设计表示肯定,毕竟像我
    一博科技 2025-01-21 16:17 100浏览
  • 临近春节,各方社交及应酬也变得多起来了,甚至一月份就排满了各式约见。有的是关系好的专业朋友的周末“恳谈会”,基本是关于2025年经济预判的话题,以及如何稳定工作等话题;但更多的预约是来自几个客户老板及副总裁们的见面,他们为今年的经济预判与企业发展焦虑而来。在聊天过程中,我发现今年的聊天有个很有意思的“点”,挺多人尤其关心我到底是怎么成长成现在的多领域风格的,还能掌握一些经济趋势的分析能力,到底学过哪些专业、在企业管过哪些具体事情?单单就这个一个月内,我就重复了数次“为什么”,再辅以我上次写的:《
    牛言喵语 2025-01-22 17:10 38浏览
  • 数字隔离芯片是一种实现电气隔离功能的集成电路,在工业自动化、汽车电子、光伏储能与电力通信等领域的电气系统中发挥着至关重要的作用。其不仅可令高、低压系统之间相互独立,提高低压系统的抗干扰能力,同时还可确保高、低压系统之间的安全交互,使系统稳定工作,并避免操作者遭受来自高压系统的电击伤害。典型数字隔离芯片的简化原理图值得一提的是,数字隔离芯片历经多年发展,其应用范围已十分广泛,凡涉及到在高、低压系统之间进行信号传输的场景中基本都需要应用到此种芯片。那么,电气工程师在进行电路设计时到底该如何评估选择一
    华普微HOPERF 2025-01-20 16:50 73浏览
  • Ubuntu20.04默认情况下为root账号自动登录,本文介绍如何取消root账号自动登录,改为通过输入账号密码登录,使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568,四核A55处理器,主频2.0Ghz,1T算力NPU;支持OpenHarmony5.0及Linux、Android等操作系统,接口丰富,开发评估快人一步!添加新账号1、使用adduser命令来添加新用户,用户名以industio为例,系统会提示设置密码以及其他信息,您可以根据需要填写或跳过,命令如下:root@id
    Industio_触觉智能 2025-01-17 14:14 121浏览
  • 2024年是很平淡的一年,能保住饭碗就是万幸了,公司业绩不好,跳槽又不敢跳,还有一个原因就是老板对我们这些员工还是很好的,碍于人情也不能在公司困难时去雪上加霜。在工作其间遇到的大问题没有,小问题还是有不少,这里就举一两个来说一下。第一个就是,先看下下面的这个封装,你能猜出它的引脚间距是多少吗?这种排线座比较常规的是0.6mm间距(即排线是0.3mm间距)的,而这个规格也是我们用得最多的,所以我们按惯性思维来看的话,就会认为这个座子就是0.6mm间距的,这样往往就不会去细看规格书了,所以这次的运气
    wuliangu 2025-01-21 00:15 183浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦