关于float浮点值二进制存储和运算精度损失的话题
1.前言
浮点值的存储、运算都可能会带来精度损失,了解精度损失背后的机制原因方便我们更好的了解什么情况下会发生精度损失、什么情况下精度损失较大,以及思考怎么避免或减少精度损失。
2.知识点
(1)IEEE 754标准
EEE 754标准(电气和电子工程师协会,简称IEEE)是目前通用的浮点数表示规范,它为单精度(float)、双精度(double)和扩展精度(如long double)浮点数定义了一套标准化的二进制编码方案。
根据该标准,浮点数可以表示为:
如5.5=
(2)二进制排列规则
IEEE754 单精度(32位)的二进制排列规则:符号位S(1位,0为正数,1为负数) + 阶码E(8位) + 尾数M(23位)。
IEEE754 双精度(64位)的二进制排列规则:符号位S(1位,0为正数,1为负数) + 阶码E(11位) + 尾数M(52位)。
(3)阶码偏置
为了将阶码转换为无符号整数,以简化硬件实现,同时避免阶码出现特殊值0和255,设计了阶码偏置的规则。
单精度的偏置常数为127(固定值),即阶码 = 127 + 阶(左移为正数,右移为负数)。
双精度的偏置常数为1023(固定值),即阶码 = 1023 + 阶(左移为正数,右移为负数)。
根据上述知识点,float值的二进度排列如下图所示:
3. 示例
为方便理解,我们以float值98.204590为例进行二进制存储的说明。
步骤①:将整数部分整除以2,取余数部分倒序排列
98 / 2 = 49 余 0
49 / 2 = 24 余 1
24 / 2 = 12 余 0
12 / 2 = 6 余 0
6 / 2 = 3 余 0
3 / 2 = 1 余 1
1 / 2 = 0 余 1
整数部分二进制为:1100010。
步骤②:将小数部分乘以2,取商的整数部分正序排列( 一直乘 2 ,遇到 1 退出;如果乘 2 之后的数字大于 1,则减去 1 )
根据上述排列可知,尾数可以取23位,但由于小数点前面的1.不用显式表示,这样可以取24位,由于上面整数部分占据了7位,这样小数部分取17位:00110100011000000。
这样98.204590表示为:1100010.00110100011000000。
0.204590 * 2 = 0.40918 商的整数部分0
0.40918 * 2 = 0.81836 商的整数部分0
0.81836 * 2 = 1.63672 商的整数部分1
0.63672 * 2 = 1.27344 商的整数部分1
0.27344 * 2 = 0.54688 商的整数部分0
0.54688 * 2 = 1.09376 商的整数部分1
0.09376 * 2 = 0.18752 商的整数部分0
0.18752 * 2 = 0.37504 商的整数部分0
0.37504 * 2 = 0.75008 商的整数部分0
0.75008 * 2 = 1.50016 商的整数部分1
0.50016 * 2 = 1.00032 商的整数部分1
0.00032 * 2 = 0.00064 商的整数部分0
0.00064 * 2 = 0.00128 商的整数部分0
0.00128 * 2 = 0.00256 商的整数部分0
0.00256 * 2 = 0.00512 商的整数部分0
0.00512 * 2 = 0.01024 商的整数部分0
0.01024 * 2 = 0.02048 商的整数部分0
0.02048 * 2 = 0.04096 商的整数部分0
0.04096 * 2 = 0.08192 商的整数部分0
步骤③:小数点向左移,直到整数部分为1
1100010.00110100011000000处理后为1.10001000110100011000000 * 2^6
阶为6,偏置127即133,占8位为:1000 0101
步骤④:根据数值的正负定义符号位
由于数值为正,所以符号位S为0。
步骤⑤:根据知识点一进行数值组装
此二进制值为98.20458984375,意味着在二进制表示和存储阶段即有精度损失了。
4.精度相关话题
4.1. 存在一个浮点常量,其他浮点值加上它之后小数点后值不变吗?
不存在,在计算机中浮点值相加并不是简单的整数+整数,小数+小数,其结果在转为二进制存储阶段也有可能会继续损失精度。
有些情况下我们可能需要把浮点值偏置处理为某个范围再继续进行应用,这种处理很可能会带来精度损失。
4.2. 尽量减少浮点数据的处理和运算
尽量减少浮点数据的处理和运算,每次运算都可能会损失精度,在有些算法计算中尽量采用逻辑清晰简便的处理过程,减少精度损失。如求向量夹角,需要尽量简化运算过程,以保持较高的结果精度。想想为什么公式推导很重要?化繁为简!便于应用。
4.3. 尽量减少溢出运算
每次溢出都会损失精度,在数学类的计算或几何算法中是一个绕不开的话题。后续博主可能会开一个系列讲几何算法中提高精度的一些经验措施。
4.4. 关注浮点值的标识范围
关注浮点值的标识范围,避免超出范围的计算处理,如果可能超出范围则用更高范围和精度的类型或采用其他处理办法。
想想为什么4字节float表示范围约为?
我们看看阶码,阶码为8位,由阶偏置127得到,这样阶最大为
也就是上述范围。
5. 参考文章
1、二进制转换网站:
IEEE 754 浮点数转换 - 锤子在线工具
2、浮点数的二进制表示
浮点数的二进制表示_浮点 二进制-CSDN博客
3、大白话说float型的精度和范围
大白话说float型的精度和范围_float范围值的大小-CSDN博客
4、 float的精度和取值范围
float的精度和取值范围_float精度-CSDN博客
5、浅谈C/C++的浮点数在内存中的存储方式
http://t.csdnimg.cn/9xzXI
浅谈C/C++的浮点数在内存中的存储方式-CSDN博客
6、C++/C--浮点型数据的二进制表示及其内存存储形式
C++/C--浮点型数据的二进制表示及其内存存储形式_c++输出浮点数的二进制形式-CSDN博客
7、深入理解浮点数:阶码为什么要加上偏移量等4个问题
深入理解浮点数:阶码为什么要加上偏移量等4个问题_阶码为什么加127-CSDN博客
8、计算机组成原理:浮点数的加、减、乘、除运算(含实例完整运算)
计算机组成原理:浮点数的加、减、乘、除运算(含实例完整运算)_浮点数运算-CSDN博客
相关文章:

关于float浮点值二进制存储和运算精度损失的话题
1.前言 浮点值的存储、运算都可能会带来精度损失,了解精度损失背后的机制原因方便我们更好的了解什么情况下会发生精度损失、什么情况下精度损失较大,以及思考怎么避免或减少精度损失。 2.知识点 (1)IEEE 754标准 EEE 754标准…...

python爬虫学习记录-请求模块urllib3
(文章内容仅作学习交流使用) urllib3是一个功能强大、条理清晰,用于HTTP客户端的第三方模块 urllib3-发送网络请求 使用urllib3发送网络请求时,需要先创建PoolManager对象,并使用该对象的request方法发送请求&#…...

谷粒商城实战笔记-133~135-城业务-商品上架-远程上架接口
文章目录 一,谷粒商城实战笔记-133-城业务-商品上架-远程上架接口1,开发目标2,详细设计2.1,提前建立索引2.2,构造批量操作请求参数2.3,使用HighLevelClient调用bulk请求保存数据 二,134-商城业务…...

【React】详解 App.js 文件
文章目录 一、App.js文件的基本结构1. 引入必要的模块2. 定义根组件3. 导出根组件 二、App.js文件的详细解析1. 函数组件与类组件函数组件类组件 2. 使用CSS模块3. 组织子组件4. 管理组件状态使用useState钩子使用state对象 三、App.js文件的最佳实践1. 保持组件的简洁和模块化…...

【ML】self-supervised Learning for speech and Image
【ML】self-supervised Learning for speech and Image 1. self-supervised Learning for speech and Image1.1 自监督学习在语音处理领域的方法及其特点1.2 自监督学习在图像处理领域的方法及其特点 2. Predictive Approach2.1 特点2.2 适用场景 3. contrastive Learning4. 语…...
青岛实训day24(8/8)
一.Python环境准备 1.查看有没有python3 yum list installed |grep python yum list |grep python3 最新安装3.12可以使用源码安装 2.下载安装python3 yum -y install python3 3.查看版本 [rootpython ~]# python3 --version Python 3.6.8 4.进入编辑 [r…...
*算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
刷题记录 101. 孤岛的总面积DFSBFS 102. 沉没孤岛DFSBFS *103. 水流问题*104. 建造最大岛屿 101. 孤岛的总面积 题目地址 本题要求不与矩阵边缘相连的孤岛的总面积。先将与四个边缘相连的岛屿变为海洋,再统计剩余的孤岛的总面积。无需再标识访问过的结点ÿ…...
设计模式 由浅入深(待完结)
一、设计模式是什么? 设计模式是指在软件开发中,经过验证的,用于解决在特定环境下,重复出现的,特定问题的解决方案。 二、设计模式有哪些? 1. 观察者模式 定义对象间的一种一对多(变化&#x…...
(第34天)645、最大二叉树
目录 645、最大二叉树题目描述思路代码 645、最大二叉树 题目描述 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大…...
Python知识点:如何使用Paramiko进行SSH连接与操作
使用Paramiko进行SSH连接与操作可以分为以下几个步骤: 安装Paramiko: 首先需要安装Paramiko库,可以使用pip进行安装: pip install paramiko建立SSH连接: 使用Paramiko连接远程服务器,需要提供服务器的地址、…...

代码随想录算法训练营第六天(一)|242.有效的字母异位词
LeetCode 242 有效的字母异位词 题目: 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。 示例 1: 输入: s "anagram&q…...
数据结构 | 考研代码题之顺序表 | 1 查找L中值为e的数据元素若找到则返回其下标,若找不到则返回-1
文章目录 1 题目2 题解 1 题目 假设有一个顺序表 L,其存储的所有数据元素均为不重复的正数,查找L中值为e的数据元素,若找到则返回其下标,若找不到则返回-1。 2 题解 C语言代码: /*假设有一个顺序表 L,其…...

RLVF:避免过度泛化地从口头反馈中学习
人工智能咨询培训老师叶梓 转载标明出处 大模型在不同行业和个人中的广泛应用要求模型能够根据具体的用户反馈进行调整或定制,以满足细微的要求和偏好。虽然通过高层次的口头反馈来指定模型调整非常方便,例如“在给老板起草电子邮件时不要使用表情符号”…...
设计原则与思想-从项目实战中学习设计模式
文章目录 开源项目通过剖析Java JDK源码学习灵活应用设计模式1. 单例模式(Singleton Pattern)示例:`java.lang.Runtime`2. 工厂模式(Factory Pattern)示例:`java.util.Date`3. 观察者模式(Observer Pattern)示例:`java.util.Observable` 和 `java.util.Observer`4. 适…...
python中的类属性、实例属性、类方法、实例方法和静态方法
1. 类属性(类变量)和实例属性(实例变量) 在python中,类中的属性就是定义在类中的变量,简称成员变量;类中的行为就是定义在类中的方法,简称成员方法。成员变量又可分为类变量和实例变量,或者分为类属性和实例属性。成员…...

A股继续底部震荡,探底是否能成功?
真心的给股民朋友提个醒,不管你胆大还是胆怯,盘面上出现了1个反常信号,一起来看看: 1、今天两市低开高走,开始筑底了,任何一个主力,都是在无人问津的熊市布局,而在人声鼎沸的牛市离场…...

NPDP考前怎么复习?NPDP200问PDF版来啦~
距离NPDP下半年考试还有4个月的时间,现在正是备考的黄金期。 以下复习建议~ 01.制定详细计划 首先,根据考试大纲,可以将内容划分为几个模块,如新产品开发流程、市场研究、产品规划等,并为每个模块设定学习目标和时间…...

ajax图书管理项目
bootstrap弹框 不离开当前页面,显示单独内容,让用户操作 功能:不离开当前页面,显示单独内容,供用户操作步骤: 1.引入bootstrap.css和bootstrap.js …...

深入理解 Java SPI - 概念、原理、应用
零、前言 在当今互联网时代,应用程序越来越复杂,对于我们开发人员来说,如何实现高效的组件化和模块化已经成为了一个重要的问题。而 Java SPI(Service Provider Interface)机制,作为一种基于接口的服务发现…...
JavaScript - 判断数组中是否包含某个的元素的几种方式
目录 1. 使用 includes 方法 2. 使用 indexOf 方法 3. 使用 find 方法 4. 使用 some 方法 5. 使用 filter 方法 6. 使用 every 方法 应该算是前端开发过程中比较常用的基本操作,话不多说,看代码。 1. 使…...
OpenCV 图像通道的分离与合并
一、知识点 1、一张彩色图像可以由R、G、B三个通道的灰度图合并而成。 2、void split(InputArray m, OutputArrayOfArrays mv); (1)、将多通道阵列划分为几个单通道阵列。 (2)、参数说明: m: 要分离的多通道阵列。 mv: 输出的vector容器,每个元素都…...

基于微信小程序的车位共享平台的设计与实现源码数据库文档
摘 要 近年来,随着国民经济的飞速发展,城镇化进程的步伐加快,城市人口急剧增长,人们的生活水平持续改善,特别是大中型城市,城市的交通规模日益增大,汽车的保有量不断提高,然而城市的…...
html如何在一张图片上的某一个区域做到点击事件
在HTML中,可以通过<map>和<area>标签来实现对图片的某个区域添加点击事件。这种方法通常用于创建图像地图(Image Map),允许用户点击图片的不同区域触发不同的事件。 以下是实现步骤和代码示例: 1. 准备图…...

Redis :String类型
String类型 String是Redis中的字符串,是Redis中最基本的数据类型,直接是按照二进制数据的进行存储 Redis中的所有key都是String类型,但是value是有差别的 常见的命令 set 将String类型的value存储到key中,如果之间有相同的ke…...
Go 中 map 的双值检测写法详解
Go 中 map 的双值检测写法详解 在 Go 中,if char, exists : pairs[s[i]]; exists { 是一种利用 Go 语言特性编写的优雅条件语句,用于检测 map 中是否存在某个键。让我们分解解释这种写法: 语法结构解析 if value, ok : mapVariable[key]; …...
如何把本地服务器变成公网服务器?内网ip网址转换到外网连接访问
内网IP只能在本地内部网络连接访问,当本地搭建服务器部署好相关网站或应用后,在局域网内可以通过内网IP访问,但在外网是无法直接访问异地内网IP端口应用的,只有公网IP和域名才能实现互联网上的访问。那么需要如何把本地服务器变…...
单元测试与QTestLib框架使用
一.单元测试的意义 在软件开发中,单元测试是指对软件中最小可测试单元(通常是函数、类的方法)进行隔离的、可重复的验证。进行单元测试具有以下重要意义: 1.提升代码质量与可靠性: 早期错误检测: 在开发…...

natapp 内网穿透失败
连不上网络错误调试排查详解 - NATAPP-内网穿透 基于ngrok的国内高速内网映射工具 如何将DNS服务器修改为114.114.114.114_百度知道 连不上/错误信息等问题解决汇总 - NATAPP-内网穿透 基于ngrok的国内高速内网映射工具 nslookup auth.natapp.cnping auth.natapp.cn...
Hadolint:Dockerfile 语法检查与最佳实践验证的终极工具
在容器化应用开发的浪潮中,Dockerfile 作为构建 Docker 镜像的核心配置文件,其质量直接影响着应用的安全性、稳定性和可维护性。然而,随着项目复杂度的增加,手动检查 Dockerfile 不仅耗时,还容易遗漏潜在问题。今天,我要向大家介绍一款强大的工具——Hadolint,它将彻底改…...
STM32开发中,线程启动异常问题排查简述
1. 参数传递问题 错误类型:线程属性错误地使用。影响:线程属性(如堆栈大小、优先级)不匹配可能导致线程创建失败或行为异常。验证方法:检查 线程创建的返回值,若为 NULL 则表示线程创建失败。 2. 系统资源…...