当前位置: 首页 > news >正文

数据在内存中的存储(超详细讲解)

目录

浮点数家族

浮点数类型在内存中的存储

一.为什么说整型和浮点数在内存中存储方式不同(证明)

二.浮点数的存储规则

浮点数在计算机内部的表示方法

1.对于M的存储和取出规则

2.对于E的存储和取出时的规则

对前面代码结果进行解释:

代码:

解释如图:


浮点数家族

包括 :float,double,long  double

整型家族类型,表示的范围可以在 “limits.h”里查看

浮点数家族表示的范围在 “float.h” 中定义(可以在这里面查浮点数类型表示的精度,最大最小值等...)

以查看浮点数范围为例,打开float.h文件

如:


浮点数类型在内存中的存储

一.为什么说整型和浮点数在内存中存储方式不同(证明)

可以通过一个代码来解释整型和浮点数在内存中的存储方式是不同的

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>int main()
{int n = 9;float* pFloat = (float*)&n;printf("n的值为:%d\n", n);printf("*pFloat的值为:%f\n", *pFloat);*pFloat = 9.0;printf("num的值为:%d\n", n);printf("*pFloat的值为:%f\n",*pFloat);return 0;
}

运行结果:

运行结果分析:如果整型类型和浮点数类型的存储的方式一样,

预期结果应该是 9     9.00000     9      9.000000 

所以通过这个结果可以看出整型和浮点型在内存中存储的方式有一定的差异


二.浮点数的存储规则

浮点数在计算机内部的表示方法

根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式: (-1)^S * M * 2^E (-1)^S 表示符号位,当S=0,V为正数;当S=1,V为负数。 M表示有效数字,大于等于1,小于2。 2^E表示指数位。

举例来说: 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。 那么,按照上面V的格式,可以得出S=0,M=1.01,E=2;

十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2;

并且IEEE 754规定:

对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

特别注意的是对M和E的存储还有特别之处 

1.对于M的存储和取出规则

首先,M的范围是1<=M<2的数,都可以写成1.xxxxxxx的形式,每个M小数点前面都有1,所以存出的时候只需要把小数点后面的xxxxxxx存储起来,取出的时候再统一在小数点前面加上1;这样的好处是:以32位 浮点数为例,留给M只有23位, 将第一位的1舍去以后,等于可以保存24位有效数字。

2.对于E的存储和取出时的规则

首先,E为一个无符号整数(unsigned int)

因为无符号整数只能表示正数,但是科学计数法中E是可以为负数,所以IEEE 754规定E在存入内存中时加上一个中间值,,对于8位的E,这个中间数 是127;对于11位的E,这个中间 数是1023。

比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即 10001001;又如2^-2的E是-2,所以保存成32位浮点数时,必须保存-2+127=125,即01111101,让E变为正数;

指数E从内存中取出还可以再分成三种情况:

1.不全为0和不全为1

E在存储时加了中间值 127 / 1023 ,所以E在取出时用减去 127 / 1023 ,得到真实值

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

2.E全为0时

浮点数的指数E等于1-127(或者1-1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于 0的很小的数字(即为什么下图结果为0.00000)

 3.E全为1

即2^E,例:E为8位时,11111111转换为十进制为255,即2^255,是个很大的数了,更不用说11位的E了;所以,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);


对前面代码结果进行解释:

代码:

int main()
{int n = 9;float* pFloat = (float*)&n;printf("n的值为:%d\n", n);printf("*pFloat的值为:%f\n", *pFloat);*pFloat = 9.0;printf("num的值为:%d\n", n);printf("*pFloat的值为:%f\n", *pFloat);return 0;
}

解释如图:


http://www.lryc.cn/news/91048.html

相关文章:

  • log4cplus使用示例
  • 人工智能学习07--pytorch20--目标检测:COCO数据集介绍+pycocotools简单使用
  • learnOpenGL-深度测试
  • 阿里云服务器数据盘是什么?系统盘和数据盘区别
  • linux常用命令精选
  • 人体行为足力特征分析及其应用研究_kaic
  • javascript基础二十七:说说 JavaScript 数字精度丢失的问题,解决方案?
  • 重塑工作场所:后疫情时代组织韧性的8个策略
  • TCP协议为什么要三次握手而不是两次?
  • 使用Vuex进行状态管理
  • 【优化调度】基于改进遗传算法的公交车调度排班优化的研究与实现(Matlab代码实现)
  • IMX6ULL裸机篇之I2C实验-硬件原理图
  • 华为OD机试真题 Java 实现【获取字符串中连续出现次数第k多的字母的次数】【2023Q1 100分】,附详细解题思路
  • 充分统计量和因子分解定理
  • M1 PD安装arm ubuntu及Docker
  • TCP协议的RST标志
  • 【软件质量与软件测试 白盒测试与黑盒测试】
  • JavaScript教程(高级)
  • C++进阶 —— 范围for(C++11新特性)
  • ELK +Filebeat日志分析系统
  • 万字解析PELT算法!
  • 腾讯云服务器端口怎么全开?教程来了
  • 深入理解Java虚拟机:JVM高级特性与最佳实践-总结-13
  • 租售keysight E8257D 50G模拟信号发生器 销售/回收
  • 【C++】什么是函数模板/类模板?
  • 为什么是ChatGPT引发了AI浪潮?
  • 批处理文件(.bat)启动redis及任何软件(同理)
  • 深度学习求解稀疏最优控制问题的并行化算法
  • 牛客网项目—开发社区首页
  • uniapp水文【uniapp】