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

从0开始的C语言(八)浮点类型

下面我们来看一下浮点数和浮点类型

浮点数说白了就是小数, 而浮点类型,常用的有单精度浮点类型float 和 双精度浮点类型double

尾数(基数):一共有多少个有效数字,如3.14159的尾数(基数)就是6

指数:在浮点数存储之中确定小数点的位置,用来存10的几次幂

计算机储存浮点数也是以二进制去存储的

浮点数IEEE754指数偏移存储原理

首先我们可以通过sizeof(float)知道 单精度类型float的字节大小是4字节,也就是32位,

而这32位当中,符号位占1位, 指数位占8位

那么剩下的基数(也就是尾数)就占了23位, 加在一起正好32位

(别问我为什么这样安排,它就是这样儿!)

那就有闲的没事的人要问了,那这个8位的指数是怎么存的呢???

这里我们要声明一下,C语言的存储方式都是二进制

所以这个指数它肯定也是以二进制的方式进行存储的

那么这个八位的指数它具体该怎么以二进制的形式去存储呢?

这就要设计到一个叫做IEEE754的标准,这个标准就是定义 单精度float类型 那八位的指数 是怎么存储的

首先要说一下,符号位只有整个浮点数的开头才有,并且仅此一个,没有别的符号位了

所以指数的那八位里面没有符号位,全都是有效位

因为有八位,所以指数可以表示256个数(从0 到 255, 因为0000 0000 是0 1111 1111 是255)

而IEEE754给了一个特别巧妙的设计,它们把正负数都存到了这256个数里面

即不管浮点数的指数幂 是正的还是负的都可以用这个标准来表达

那么,是怎么用这个指数来表示正数和负数的呢?它有一个很巧妙的设计:

因为有256个数(从0 到 255), 所以对255 / 2 去掉小数点得到 127

于是就以这个127为标准, 即把127看做是0

然后往127的左边去的值叫做左偏移, 往127右边去的值叫做右偏移

(此处可以看成往左边是递减,往右边是递增)

例如,127往左边偏移一位,变成126,这就意味着 127 - 1,所以呢,如果指数的这八位最后存储

的是126的二进制数,就意味着, 该浮点数的指数是 10的-1次幂

如果是往右边偏移的话,例如指数的值是130, 即指数的这八位存储的是130的二进制数,那就意味着127往右边偏移了3位, 即 127 + 3, 就意味着, 该浮点数的指数是 10的+3次幂

IEEE754就是用这个区间 来去判断 浮点数的10的次幂是正的还是负的

例如:314159 * 10的-5次方 存到内存的时候, 首先这个数是正数,所以符号位是0

然后该数的基数(尾数)是314159, 直接转换成二进制数存到基数的23位里,

最后看指数,既然指数是 10 的-5次幂, 所以计算机判断出来是 127往左边偏移了5位, 即122

然后再把122转换为二进制数,最后存储到指数的 那八位的空间里,代表是10 的-5次幂

这个314159 * 10的-5次幂到此就存完了

大于1的浮点数是规范化浮点数(比如2.5 , 5.14 9.527)

小于1的是非规范化浮点数(比如0.99 , 0.28, 0.284)

下图的讲解就对应了我们上面说的IEEE754标准:

float类型占4字节,即32位,其中正负号占一位,中间的占23位,指数幂占八位

但其实中间那23位还有一个隐藏的第24位(隐式的位)以防不备之时(应对下溢underflow)

至于下溢是什么,我们马上就会讲解

浮点数的大小并不是由 基数(尾数)那23位 决定的,而是由指数那8位决定的

float是单精度,double是双精度

并且要注意,给float类型的变量赋值时,最好在赋的数值后面加上后缀f/F来标注出是float变量

给变量名命名不要起a,b,c这种的意义不明的名字,要起的容易理解,起的有意义,或者就是在描述某种东西

例如:person_number , temperature, speed_of_sound , score , length , height 等等

给变量命名有两种方法:驼峰命名法和下划线命名法

驼峰命名法: PersonNumber(大驼峰命名法) personNumber(小驼峰命名法)

下划线命名法:person_number

个人更喜欢用下划线命名法一点~

Float变量用%f来格式化输出

例子:

运行结果:

聪明的你可能注意到了输出的数据中有些丢失了精度,下面我们就来解答这个问题吧

float变量储存的数据可能会丢失精度

原因是因为给float变量赋的值要转化成二进制储存在电脑里

而浮点数小数点后面的小数部分在转换为二进制数时会发生一些误差(可能会转换为无限不循环的二进制数,你可以理解成有的小数点数转换为二进制数时除不开了所以变成了无限不循环二进制数)

所以会导致数值在小黑框中输出时会有一些数值上的误差

在定义float类型变量时一定要加上后缀f/F来告知别人这是float类型,提醒别人可能会发生丢失精度的问题

小扩展:在C语言的printf里,想要输出%符号,只需要打出两个%即可,即“%%”就可以输出一个%了

关于%E和%A:

例子:

运行结果:

%e和%E 以及 %a和%A只有小写和大写的区别,除此之外都一样

http://www.cnnetsun.cn/news/2949439.html

相关文章:

  • Poppins几何字体终极指南:9种字重免费下载与完整使用教程
  • Steam挂卡神器Idle Master完整教程:自动收集交易卡轻松提升Steam等级
  • 基于TWR-WIFI-AR4100的嵌入式Web服务器开发与HVAC远程控制实战
  • CTFAK 2.0完全指南:Clickteam Fusion游戏资源解包与逆向分析终极工具
  • AI科技热点日报 | 2026年06月16日
  • HMCL内存优化终极指南:让低配电脑流畅运行高版本Minecraft的完整解决方案
  • 基于LLM的自动化渗透测试:原理、本地部署与智能体实践
  • 如何快速在Mac上实现专业级桌面歌词显示:LyricsX完整指南
  • OWAS开源Web应用安全实战:从OWASP Top 10到自动化防御体系构建
  • MAA明日方舟自动化助手终极指南:如何高效解放双手,告别重复劳动
  • Obsidian Outliner终极指南:如何用拖拽功能实现高效列表管理
  • 赛马娘DMM版中文汉化与性能优化全攻略:告别日文界面与卡顿烦恼
  • ArduinoFFT技术深度解析与嵌入式信号处理实战应用
  • 视频转GIF终极指南:如何用Gifski在Mac上制作高质量动画
  • RTOS多任务下的I2C通信:用FreeRTOS信号量实战解决温湿度传感器与光照传感器的总线竞争
  • AI秒出答案的时代,别让快速回复废掉你的深度思考
  • 基于MQX RTOS的嵌入式网络化HVAC控制系统开发实践
  • 通达信缠论自动分析插件终极指南:三分钟解锁专业级技术分析能力
  • 别再重启Unity了!遇到WakeUp为空报错,试试这个更快的修复方法
  • 出生公证书怎么办理?出生公证需要什么材料?
  • Expression树缓存键设计:基于IComparer的高效比较与SortedList优化
  • CBconvert终极指南:如何免费快速解决漫画格式兼容问题
  • 避坑指南:STM32CubeMX配置RTC入侵检测时,滤波和触发方式到底怎么选?
  • TypeScript博客迁移实战:用OOP思想重构静态站点架构
  • NanaZip:Windows 11时代的智能压缩工具,让你的文件管理更高效
  • 告别C1083!一次搞懂QT+MSVC开发环境配置的‘路径玄学’
  • 别再用默认配置了!手把手教你复现VSFTPD 2.3.4笑脸后门漏洞,附Metasploit实战
  • LM-DP-SGD:层感知差分隐私保护深度学习模型
  • Python 下划线 _ 的六种用法与语义设计哲学
  • SolidWorks第四部分_直接实体建模特征9_替换面原理