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

深入解析内存中的整数与浮点数存储

一、整数在内存中的存储

        首先,整数的2进制表示方法有三种,分别是原码、反码和补码。整数在内存中存储的是二进制的补码。补码又分为符号位和数值位两部分,最高位的一位是符号位,用‘0’表示正数,用‘1’表示负数;其余则是数值位。不过,我们在调试窗口中观察内存时,为了方便展示,显示的是16进制的值,如下图所示

二、大小端        

        从上图中可以看到,为什么我们给n赋值位0x11223344,在内存中观察的时候是44 33 22 11呢?这就要引出新的概念”大小端“了。

        所谓大端(存储)模式,是指数据的低位字节内容保存在内存的高地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。而小端(存储)模式是指数据的低位字节内容保存在内存的==低==地址处,⽽数据的==⾼==位字节内容,保存在内存的⾼地址处。

        下面我们用几段代码来切实的感受下大小端的不同。

#include <stdio.h>
int main()
{int n=1; //转为16进制位:0x00 00 00 01  在左边的是高位,右边的是低位// 内存               低位 ---> 高位// 在大端模式下存储的是:00 00 00 01// 在小端模式下存储的是:01 00 00 00return 0;
}

        从上述代码中可以感受到大端和小端的具体不同之处,那么我们怎么判断所用机器是大端还是小端呢?

#include <stdio.h>int check_sys()
{int n = 1;		//十六进制表示为0x00 00 00 01return *(char*)&n;	//将n的地址强制转化位char*类型,然后解引用,即可取出最低一位地址对应的数字,然后判断它的值即可//小端:01 00 00 00 //大端:00 00 00 01
}int main()
{int ret = check_sys();	if (ret == 1)printf("小端\n");	 elseprintf("大端\n");	return 0;
}

        下面我们做个练习来巩固下学习成果吧。(解析在文章末尾

#include <stdio.h>
//X86环境⼩端模式下,输出结果是什么?int main()
{int a[4] = { 1, 2, 3, 4 };			int* ptr1 = (int*)(&a + 1);			int* ptr2 = (int*)((int)a + 1);		printf("%x,%x", ptr1[-1], *ptr2);	return 0;
}

三、浮点数在内存中的存储

        浮点数在内存中存储时首先还是将十进制转换为二进制,使用乘2取整法就可以啦(将小数部分不断乘以2,记录整数部分(0或1),直到小鼠部分为0或达到所需精度,最后将整数部分顺序排列)。

        浮点数转换为二进制时,小数点后数字的权重分别是2^(-1),2^(-2),2^(-3),……

        按照国际标准IEEE 754,我们需要将二进制浮点数V表示为以下形式:

        V=(-1)^S  * M * 2^E

        1. (−1)^S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
        2. M 表⽰有效数字,M是⼤于等于1,⼩于2的
        3. 2^E  表⽰指数位,E为⼀个⽆符号整数

        举两个例子,⼗进制的5.0,写成⼆进制是 101.0 ,相当于 1.01×2^2,可以得出S=0,M=1.01,E=2;⼗进制的-5.0,写成⼆进制是:-101.0 ,相当于-1.01×2^2 。那么,S=1,M=1.01,E=2。

        在内存中时按照 S E M 的顺序依次存储的,有以下要求:

        1.对于32位的浮点数(float),最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
         2. 对于64位的浮点数(double),最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

        存储有效数字 M 和指数 E 时,还有一些特别的规定

        1.在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后⾯的小数部分。⽐如保存1.01的时候,只保存01,等到读取的时候,再把第⼀位的1加上去

        2.存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023

四、浮点数取的过程

        浮点数在取时可分为3种情况。

        E 不全为0或1时

        指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第⼀位的1

        E 全为0时

        浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,⽽是还原为0.xxxxxx的⼩数。这样做是为了表⽰±0,以及接近于0的很⼩的数字        

        E 全为1时

        如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s)

        做个题目巩固下浮点数的学习成果吧。(解析在最后)

#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("n的值为:%d\n", n);				printf("*pFloat的值为:%f\n", *pFloat);	return 0;
}

五、题目解析

第一题

#include <stdio.h>
//X86环境⼩端字节序int main()
{int a[4] = { 1, 2, 3, 4 };			//在小端模式下的存储如下//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00int* ptr1 = (int*)(&a + 1);			//指针+1取决于指针的类型int* ptr2 = (int*)((int)a + 1);		//整数+1就是+1,向后走一个字节,跳过01,访问的是00 00 00 02//因为是小端模式,所以低地址存的是低字节数据,访问的是20 00 00 00printf("%x,%x", ptr1[-1], *ptr2);	//4,2000000return 0;
}

第二题

#include <stdio.h>int main()
{int n = 9;//二进制:1001->补码:00000000 00000000 00000000 00001001//用浮点数视角看的话就是:0 00000000 00000000 00000000 0001001//E=1-127=-126//E全为0,有效数字M,取出后不再加上第一位的1//(-1)^0 * 0.00000000 00000000 0001001 * 2^(-126) -> 无限接近于0,看作0float* pFloat = (float*)&n;printf("n的值为:%d\n", n);				//9printf("*pFloat的值为:%f\n", *pFloat);	//0.000000*pFloat = 9.0;	//以浮点数的视角存储9.0//(-1)^0 * 1.001 * 2^3//S=0,M=1.001,E=3// 3+127=130    //0    130    3(001)         //0 10000010 00100000 00000000 0000000printf("n的值为:%d\n", n);				//1091567616printf("*pFloat的值为:%f\n", *pFloat);	//9.000000return 0;
}

http://www.dtcms.com/a/495321.html

相关文章:

  • 网站你懂我意思正能量免费软件山西格泰网站建设
  • 网站栏目变了怎么做跳转关键词网站排名查询
  • Android 集成指南:Google 登录、Facebook 登录 与 Firebase 深入接入(实战)
  • python 单词搜索(回溯-矩阵-字符串-中等)含源码(二十)
  • hot 100 | 一文讲清动态规划
  • 操作简单稳定选巨 椰 云手机
  • 设计模式之:工厂方法模式
  • 西宁市精神文明建设网站餐饮店面装饰设计
  • 对营销网站建设评估及分析佛山顺德做网站
  • 高并发系统架构设计原则:无状态、水平扩展、异步化、缓存优先
  • 系统架构设计师备考第45天——软件架构演化评估方法和维护
  • 基于SpringBoot+Vue的社区诊所管理系统(AI问答、webSocket实时聊天、Echarts图形化分析)
  • 【MySQL】第二章 基本的SELECT语句
  • Linux中软中断tasklet任务队列初始化
  • 网站制作的重要流程世界优秀摄影作品网站
  • 技术剖析:智能体工作流与RPA流程自动化的架构差异与融合实现
  • 深圳比斯特自动化|圆柱电池测试设备核心功能与技术发展解析
  • 【软考备考】系统架构设计需要考虑的因素 性能 、安全、成本、可维护性详解知识点五
  • 面试反馈 Spring Cloud 的25连环炮
  • 第八篇: `lsmod`, `modinfo`, `modprobe` - 深入内核模块
  • aspx网站服务器失去响应天工网工程新希望官网
  • 网站服务器要多少钱【邯郸网络推广公司|邯郸网络营销公司】
  • 做网站用什么域名比较好找公司开发网站
  • 【Python】求解GPS未知及高斯噪声
  • Linux 教程:如何查找服务器中的大文件
  • 计算机网络基础篇——应用层
  • 2025年主流外贸管理软件深度测评和选型策略咨询报告
  • 玩Android Harmony next版,通过项目了解harmony项目快速搭建开发
  • 公司免费网站域名申请免费网址
  • 华为鲲鹏 Aarch64 环境下多 Oracle 数据库汇聚操作指南 CMP(类 Cloudera CDP 7.3)