良人从零开始的踩坑笔记:浮点数
浮点数,真的很难学
- 什么是浮点数
- 浮点数的存储标准:IEEE754
- 浮点数的数学表示:Sign,Exponent和Significand
- 浮点数的数据类型:float与double
- 浮点数的数值范围
- float的正规数取值范围
- double的正规数取值范围
- 浮点数的特殊取值
- 次正规数Denorms
- 浮点数与其他数制的转换
- 浮点数运算
- 五种异常情况
- 浮点数加法
- 1.对阶
- 2.尾数加减
- 3.尾数规格化
- 4.舍入
- 5.校验
因为我上课没好好听
什么是浮点数
浮点数,是与定点数相对的概念,指小数点位置约定在固定位置的数。
浮点数的存储标准:IEEE754
浮点数在计算机中以遵循IEEE754浮点数计数标准的方式存储。
IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。
浮点数的数学表示:Sign,Exponent和Significand
存在一个浮点数X,则X的数学表示为
X=(−1)S×M×REX=(-1)^{S}\times M\times R^{E} X=(−1)S×M×RE
S,Sign:符号位,决定该浮点数的正负
M,Mantissa/Significand:尾数,取值为[1,2)的二进制小数,长成1.xxxxxx这样。
R,Radix base:基数,一般是2。
E,Exponent:阶/指数,二进制定点(无符号)整数。
考试的时候问你尾数是什么,你要回答小数点后那部分xxxxx
在基数R一定的情况下:
尾数M的位数反映数X的有效位数,它决定了数的表示精度,有效位数越多,表示精度越高。
阶E的位数决定数X的表示范围,值确定了小数点的位置。
M越长,X越精确
E越大,X越大
浮点数的数据类型:float与double
IEEE754规定浮点数有单精确度、双精确度、延伸单精确度与延伸双精确度四种类型,但是本文只对单精确度float与双精确度double类型作分析学习。
在科学计数法中指数是可以取负数的,所以IEEE754规定计算机存储浮点数时,阶E需要在真实值基础上再减去一个偏移值bias,即127(for float)或1023(for double) 得到阶E的移码 即阶码
规格化尾数M( 1.xxxxx )的小数点后第一位总是1,故规定第一位默认的1被省略,由此用23个数表示24位尾数。
浮点数的数值范围
绝对值范围为:
2−(2e−1)×2−m≤∣X∣≤(1−2−m)×2(2m−1)2^{-(2^{e}-1)} \times 2^{-m} \leq \left | X \right |\leq (1-2^{-m}) \times 2^{(2^{m}-1)} 2−(2e−1)×2−m≤∣X∣≤(1−2−m)×2(2m−1)
其中e和m分别表示阶数与尾数的位数
float的正规数取值范围
在32位浮点数float中,符号位占1位,尾数占23位,阶数占8位。
不考虑阶数全为0或全为1的情况下,8位二进制数取值范围即[1,254]减去其偏移量127,得到阶数E的范围为 [-126,127]。
在正常情况下,阶数不包括全为0或全为1的情况
实际的指数值 -127(保存为全0)以及 +128(保存为全 1)保留用作特殊值(见下文)
正数最小值为
Sign | Exponent | Mantissa |
---|---|---|
0 | 00000001 | 00000000000000000000000 |
1.00...0×200...1=1×2−126=2−1261.00...0 \times 2^{00...1}=1 \times 2^{-126}=2^{-126} 1.00...0×200...1=1×2−126=2−126
正数最大值为
Sign | Exponent | Mantissa |
---|---|---|
0 | 11111110 | 11111111111111111111111 |
1.11...1×211111110=(2−2−23)×2127≈3.4028234664×10381.11...1 \times 2^{11111110}=(2-2^{-23}) \times 2^{127} \approx 3.4028234664 \times 10^{38} 1.11...1×211111110=(2−2−23)×2127≈3.4028234664×1038
于是对于正浮点数有:
1.0×2−126≈1.1755×10−38≤FloatNum≤(2−2−23)×2127≈3.4028×10381.0 \times 2^{-126} \approx 1.1755 \times 10^{-38} \leq FloatNum \leq (2-2^{-23}) \times 2^{127} \approx 3.4028 \times 10^{38} 1.0×2−126≈1.1755×10−38≤FloatNum≤(2−2−23)×2127≈3.4028×1038
同理对于负浮点数有
−(2−2−23)×2127≈−3.4028×1038≤FloatNum≤−1.0×2−126≈−1.1755×10−38≈3.4028×10−38-(2-2^{-23}) \times 2^{127} \approx -3.4028 \times 10^{38} \leq FloatNum \leq -1.0 \times 2^{-126} \approx -1.1755 \times 10^{-38} \approx 3.4028 \times 10^{-38} −(2−2−23)×2127≈−3.4028×1038≤FloatNum≤−1.0×2−126≈−1.1755×10−38≈3.4028×10−38
double的正规数取值范围
在64位浮点数中,符号位占1位,尾数占52位,阶数占11位。
不考虑阶数全为0或全为1的情况下,11位二进制数取值范围即[1,2046]减去其偏移量1023,得到阶数E的范围为 [-1022,1023]。
实际的指数值 -1023(保存为全0)以及 +1024(保存为全 1)保留用作特殊值
正数最小值为
Sign | Exponent | Mantissa |
---|---|---|
0 | 00000000001 | 0000000000000000000000000000000000000000000000000000 |
1.00...0×200...1=1×2−1022=2−10221.00...0 \times 2^{00...1}=1 \times 2^{-1022}=2^{-1022} 1.00...0×200...1=1×2−1022=2−1022
正数最大值为
Sign | Exponent | Mantissa |
---|---|---|
0 | 11111111110 | 1111111111111111111111111111111111111111111111111111 |
1.11...1×211...10=(2−2−52)×21023≈1.7976931348623157×103081.11...1 \times 2^{11...10}=(2-2^{-52}) \times 2^{1023} \approx 1.7976931348623157 \times 10^{308} 1.11...1×211...10=(2−2−52)×21023≈1.7976931348623157×10308
于是对于正浮点数有:
1.0×2−1022≈2.2251×10−308≤DoubleNum≤(2−2−52)×21023≈1.7977×103081.0 \times 2^{-1022} \approx 2.2251 \times 10^{-308} \leq DoubleNum \leq (2-2^{-52}) \times 2^{1023} \approx 1.7977 \times 10^{308} 1.0×2−1022≈2.2251×10−308≤DoubleNum≤(2−2−52)×21023≈1.7977×10308
同理对于负浮点数有
−(2−2−52)×21023≈−1.7977×10308≤DoubleNum≤−1.0×2−1022≈−2.2251×10−308-(2-2^{-52}) \times 2^{1023} \approx -1.7977 \times 10^{308} \leq DoubleNum \leq -1.0 \times 2^{-1022} \approx -2.2251 \times 10^{-308} −(2−2−52)×21023≈−1.7977×10308≤DoubleNum≤−1.0×2−1022≈−2.2251×10−308
浮点数的特殊取值
Single-precision floating-point format:
https://en.wikipedia.org/wiki/Single-precision_floating-point_format
Double-precision floating-point format:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
这里贴一个小工具,在IEEE754的标准下手动控制输入Sign,Exponent和Mantissa的值,输出对应的十进制值,二进制值,十六进制值,非常简单直观
https://www.h-schmidt.net/FloatConverter/IEEE754.html
常见浮点数特殊值取值如下表
Sign | Exponent | Mantissa | |
---|---|---|---|
0 | Both cases valid | all zeros | all zeros |
+∞+\infty+∞ | zero | all ones | all zeros |
−∞-\infty−∞ | one | all ones | all zeros |
NaN | Both cases valid | all ones | nonzero |
Denorms | Both cases valid | all zeros | nonzero |
更多特殊值见上floating-point format from Wikipedia
次正规数Denorms
在计算机科学中,次正规数denormal numbers or denormalized numbers (now often called subnormal numbers)填补了浮点运算中以0为中心的下溢缺口。次正规数包含所有小于最小正规数的非0数。
float中的最小正规数是 2-126
double中的最小正规数是 2-1022
次正规数的尾数是含有前导零的,如0.1 × 2-1
次正规数的数学表示为
Denorms | Both cases valid | all zeros | nonzero |
---|
float中Denorms的特殊取值如下
double中Denorms的特殊取值如下
浮点数与其他数制的转换
将十进制数-0.75转换为IEEE754的单精度浮点数格式表示
(-0.75) 10 = (-0.11) 2 = (-1.1) 2 × 2-1 = (-1)s × 1.f × 2e-127
s = 1,f = 0.100…0,e = (127-1) 10 = ( 01111 1110 ) 2 ,表示为单精度浮点数格式为 1 0111 1110 1000 0000…0000 000,用十六进制表示为BF40 0000H
求IEEE754单精度浮点数C0A0 0000H的值是多少
将C0A0 0000H展开为一个32位单精度浮点数:1 10000001 010 0000…0000.
s = 1,f = (0.01) 2 = (0.25) 10 ,阶码e = (10000001) 2 = (129)10
所以其值为( -1 )s × 1.f × 2e-127 = (-1)1 × 1.25 × 2129-127 = -1.25 × 22 = -5.0
浮点数运算
五种异常情况
1.无效运算(无意义)
-运算时有一个数是非有限数,如:
加/减 ∞,0 × ∞,∞ / ∞等
-结果无效,如:
源操作数是NaN、0 / 0、x REM 0、∞ REM y等
2.除以0
结果即无限大
3.阶上溢
对于float,指[ E ]移 > 1111 1110,即大于127
4.阶下溢
对于float,指阶码exponent < 0000 0001,即小于-126
5.结果不精确
舍入时引起的异常,如1/3、1/10等不能精确表示为浮点数
浮点数加法
设Xm、Ym分别是X和Y的尾数,Xe、Ye分别是X和Y的阶码
1.对阶
对阶的目的是使两数阶码相等
小阶向大阶看齐,阶码小的数的尾数向右移,右移位数等于两个阶码差的绝对值Δe = Ye - Xe。
IEEE754尾数右移时,要将隐藏的“1”移到小数部分,高位补0,移出的低位保留到特定的“附加位”上
2.尾数加减
Xm × 2^(Xe-Ye) ± Ym
3.尾数规格化
当尾数高位为0,则需左规:尾数左移一次,阶码减一,直到MSB(阶码最高位)为1
每次阶码减一后要判断阶码是否下溢,阶码下溢则结果为0
当尾数最高位有进位,则需右规:尾数右移一次,阶码加一,直到MSB为1
每次阶码加一后要判断阶码是否上溢,阶码上溢则结果溢出
右规最多只需要一次,因为即使是最大的两个尾数相加(1.11…1+1.11…1),其结果也不会达到4,故尾数的整数部分最多有2位,保留一个隐含的"1"后,最多只有一位被右移到小数部分
4.舍入
如果尾数比规定数位长(有附加位),则需考虑舍入(舍入的方式有多种)
没写完,等我考完试
5.校验
若运算结果尾数为0,则说明结果为0,即阶码和尾数均应为0,需要将阶码也置0.
用二进制浮点数形式计算0.5 +(-0.4375)的值
(0.5)10 = 1.000 × 2-1(大阶),(-0.4375) = -1.110 × 2-2(小阶)
对阶: -1.110 × 2-2 → 0.111 × 2-1
加减: 1.000 × 2-1 + (-0.111 × 2-1) = 0.001 × 2-1
左规: 0.001 × 2-1 → 1.000 × 2-4
判断溢出:否
所以结果为1.000 × 2-4 = 0.0001000 = 1/16 = 0.0625
良人从零开始的踩坑笔记:浮点数相关推荐
- iphone se 一代 不完美越狱 14.6 视频壁纸教程(踩坑笔记)
iphone se 一代 不完美越狱 14.6 加 视频壁纸教程-踩坑笔记 越狱流程 1.爱思助手制作启动u盘 坑点: 2.越狱好后 视频壁纸软件 1.源 2.软件安装 越狱流程 1.爱思助手制作启动 ...
- OpenCV4.0.1/4.0.0/3.4.2 + Contrib + Qt5.9 + CMake3.12.1编译及踩坑笔记、Qt5+OpenCV配置、代码验证、效果图、福利彩蛋
Table of Contents 前言 Windows 10, OpenCV4.0.1, Qt5.9.3, CMake3.12.1, MinGW5.3.0 Windows 10, OpenCV4.0 ...
- Vue 踩坑笔记: 引入 ElementUI 时打包失败修复记录(ERROR in ./node_modules/element-ui/lib/theme-chalk/index.css)
Vue 踩坑笔记: 引入 ElementUI 时打包失败修复记录(ERROR in ./node_modules/element-ui/lib/theme-chalk/index.css Module ...
- Linux内核踩坑笔记
systemtap embedded C踩坑笔记戳这: https://blog.csdn.net/qq_41961459/article/details/103093912 task_struct的 ...
- 阿里云部署Tiny Tiny RSS踩坑笔记
阿里云部署Tiny Tiny RSS踩坑笔记 前言 入坑了RSS,之前的配置是阿里云部署RSSHub,配合Inoreader进行文章阅读,详情见RSS入坑指南.阿里云部署RSSHub踩坑笔记.在202 ...
- 「Java」基于Mirai的qq机器人开发踩坑笔记(其一)
目录 0. 前置操作 I. 安装MCL II. MCL自动登录配置 III. 安装IDEA插件 1. 新建Mirai项目 2. 编写主类 3. 添加外部依赖 4. IDEA运行 5. 插件打包 6. ...
- 「Java」基于Mirai的qq机器人开发踩坑笔记(其二)
目录 0. 配置机器人 1. onLoad方法 2. onEnable方法 3. 消息属性 4. 消息监听 I. 好友消息 II. 群聊消息 III. 无差别消息 5. 发送消息 I. 文本消息 II ...
- 昆仑通态触摸屏1003故障码,踩坑笔记
昆仑通态触摸屏1003故障码,踩坑笔记 第一次使用这个昆仑通态触摸屏,使用modbusRTU与金田变频器做通讯. 触摸屏在线后报1003通讯错误代码,现象是控制指令正常,但是读取不正常.读取变频器状态 ...
- EDUSOHO踩坑笔记之四十二:资讯
EDUSOHO踩坑笔记之四十二:资讯 获取资讯列表信息 GET /articles/{id} 权限 老API,需要认证 参数 字段 是否必填 描述 sort string 否 排序,'created' ...
最新文章
- 分布式消息技术 Kafka
- Web前端_项目实践01_萌娃摄影网页(纯HTML+CSS静态页面)
- 诛仙单机java数据库_诛仙2单机11职业架设教程
- Java文件的写入与读出
- Invalid maximum heap size: -Xmx
- AD637 有效值检测
- Windows11如何使用安卓子系统的Amazon Appstore
- vscode终端清屏
- 二叉树的先序、中序、后续遍历(递归)
- 防止浏览器自动填充表单
- Nagios常见问题集锦
- 浅读C Primer Plus——C语起源
- 高德地图定位失败_常见问题
- 借记来帐,借记往账,贷记来帐,贷记往账
- BP神经网络原理及Python实现
- WebLogic 10.3.1 下载地址
- linux shell 三元运算符,语法 - Bash中的三元运算符(?:)
- 编程大佬是否能记住代码?
- java一键换壁纸_Java 版下载必应每日壁纸并自动设置 Windows 系统桌面(改编自 C# 版)...
- Android挂机 屏幕,游戏蜂窝新版支持全面屏手机 简单几步教你如何设置挂机
热门文章
- pip 安装 nexmo
- html和jsp轮播,jsp页面、图片轮播
- zc706开发板的linux开发,第一篇:zc706 开箱及开发环境搭建
- python3爬虫实战姚良_Python3.X 爬虫实战(缓存与持久化)
- c语言分离个位十位百位_用c语言如何表示出一个数的个位,百位,十位
- 世界七大数学难题——千年大奖问题(转载)
- 批量压缩图片大小 – Caesium简体中文
- 阿里云虚拟机Windows系统控制台解压缩文件提示操作异常、解压缩失败的解决方案
- 566页19万字区级一网通办政务服务应用平台建设项目方案书
- Divan and bitwise operations(组合数+思维)