杂谈c语言——6.浮点数的存储

news/2024/10/5 16:30:43 标签: c语言, 算法

1.浮点数在内存中的存储

常⻅的浮点数:3.14159、1E10等,浮点数家族包括: float、double、long double 类型。 浮点数表⽰的范围: float.h 中定义

1.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;
}

输出什么呢?

答案是:

 

1.2 浮点数的存储

上⾯的代码中, num 和 *pFloat 在内存中明明是同⼀个数,为什么浮点数和整数的解读结果会差别 这么⼤?

要理解这个结果,⼀定要搞懂浮点数在计算机内部的表⽰⽅法。 根据国际标准IEEE(电⽓和电⼦⼯程协会)754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:

 举例说明:

5.5(十进制)==101.1(二进制),转换为二进制的科学计数法为1.011*2的2次方

就相当于(-1)的0次方*1.011*10的2次方

所以:

S==0;

M==1.011;

E==2;

浮点数的存储,就是存储S,M,E相关的值 !!!!!!

IEEE754规定:

1.对于32位的浮点数最⾼的1位存储符号位S接着的8位存储指数E剩下的23位存储有效数字M 

                                                float类型浮点数内存分配

2.对于64位的浮点数最⾼的1位存储符号位S接着的11位存储指数E剩下的52位存储有效数字M

                                          double类型浮点数内存分配

 2.浮点数存的过程

1.EEE754对有效数字M指数E,还有⼀些特别规定。

前⾯说过, 1≤M<2,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表⽰⼩数部分。 IEEE754规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去(即1不存储)只保存后⾯的 xxxxxx部分!!!!!!!!!!!!!!!!!!!!!!!!!!!。⽐如保存1.01的时候,只保存01,等到读取的时候,再把第⼀位的1加上去。

这样做的⽬ 的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第⼀位的1舍去以后,等于可以保 存24位有效数字。

2.⾄于指数E,情况就⽐较复杂 

⾸先,E为⼀个⽆符号整数(unsigned int)

这意味着,1.如果E为8位,它的取值范围为0~255;2.如果E为11位,它的取值范围为0~2047。但是,我 们知道,科学计数法中的E是可以出现负数的

举例:

0.5(十进制)==0.1(二进制)==1.0*2的-1次方,这就产生了负数!!!!

所以IEEE754规定,存⼊内存时E的真实值必须再加上 ⼀个中间数:

1.对于8位的E,这个中间数是127

2.对于11位的E,这个中间数是1023

⽐如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

3.浮点数取的过程 

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

1.E不全为0或不全为1

这时,浮点数就采⽤下⾯的规则表⽰,

1.指数E的计算值减去127(或1023),得到真实值

2.再将有效 数字M前加上第⼀位的1。

⽐如:0.5的⼆进制形式为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 00000000 00100000000000000000000

3.E全为1

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

1 0 11111111 00010000000000000000000

4.题目解析 

#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;
}

 

1.n在内存中的补码是

0000 0000 0000 0000 0000 0000 0000 1001

 但是pfloat取数据的时候是按照浮点数的方式去取的,即

⾸先,将 9 的⼆进制序列按照浮点数的形式拆分,得到

1.第⼀位符号位s=0

2.后⾯8位的指数 E=00000000 

3.最后23位的有效数字M=00000000000000000001001

V=(-1)^0 × 0.00000000000000000001001×2^(-126)=1.001×2^(-146)  

E全是0符合情况2,所以输出为0.0000000 

2. pfloat存储9.0 即换算成科学计数法是:1.001×2^3

1.第⼀位的符号位S=0

2.有效数字M等于001后⾯再加20个0,凑满23位

3.指数E等于3+127=130, 即10000010

所以,写成⼆进制形式,应该是S+E+M,即

0 10000010 001 0000 0000 0000 0000 0000

这个32位的⼆进制数,被当做整数来解析的时候,就是整数在内存中的补码,原码正是 1091567616 。


http://www.niftyadmin.cn/n/5691043.html

相关文章

汇编语言笔记2

7.MASM,NASM,ATT,ARM的介绍 MASM:Windows下编译汇编指令的软件,可以在DOSBox下运行 NASM:优化版的MASM,主要用于Linux操作系统 ATT:Linux默认的汇编风格(但不友好) ARM:非PC(IOT设备)的汇编,比如写51单片机打开keil4的界面可以看到ARM 8.汇编 C语言 C 之间的关系 发展历程…

【ubuntu】如何升级g++

sudo apt-get install -y software-properties-common sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt update sudo apt install g-7 -y 1&#xff09;software-properties-common software-properties-common是一个基础软件包&#xff0c;包含了add-apt-repo…

CUDA与TensorRT学习六:模型部署-CNN、模型部署-YOLOv8检测器、部署BEVFusion模型

文章目录 一、模型部署-CNN二、模型部署-YOLOv8检测器三、部署BEVFusion模型 一、模型部署-CNN 二、模型部署-YOLOv8检测器 三、部署BEVFusion模型

win11远程连接MySQL(linux版),不需安装docker容器

不想安装虚拟机&#xff0c;想在Windows 11上运行Linux。 在win11的搜索框内&#xff0c;搜索"启用或关闭"&#xff0c;出现了“启用或关闭Windows功能”&#xff0c;双击打开。 勾选"适用于Linux的Windows子系统"&#xff0c;“虚拟机平台”&#xff0c…

我的第一个创作纪念日-128天

机缘 在csdn相遇的这128天&#xff0c;本人的创作初心可以归结为以下几点&#xff1a; 促进技术交流与学习&#xff1a;CSDN成立的初衷是为了提供一个平台&#xff0c;让中国的软件开发者能够方便地交流技术心得、分享项目经验和学习资源。在这个平台上&#xff0c;开发者可以…

智能视界·大模型驱动视频矩阵管理系统

开头先配两张ER图 一张不带字段&#xff0c;一张带字段&#xff0c;剩下的内容按需拿取 1.产品介绍 产品名称&#xff1a; 智能视界大模型驱动视频矩阵管理系统 主要功能&#xff1a; 智能视频分析与识别 功能介绍&#xff1a;该系统集成先进的人工智能大模型&#xff0c;能…

CSS伪类、伪元素

CSS伪类、伪元素 一、伪类 ① :hover 鼠标&#x1f5b1;悬停时的伪类&#xff0c;如&#xff1a; /* 鼠标悬停到.box上时背景颜色变为红色 */ .box:hover {background-color: red; }② :active 鼠标&#x1f5b1;点击时的伪类&#xff0c;如&#xff1a; /* 鼠标点击时背…

解决 遇到JWT中claims中获取不到数据的问题

1.先介绍一下JWT的常规流程 用户进行登录将token储存到redis&#xff0c;然后进行其他需要验证的操作时进行验证&#xff0c;比如使用拦截器进行验证&#xff0c;那么id存储的到claims&#xff0c;因为可以在拦截器验证时将其存放到ThreadLocal中&#xff0c;这样通过ThreadLo…