基于FPGA的数字信号处理(3)--什么是浮点数?

news2024/12/28 4:57:58

科学计数法

你可能不了解「浮点数」,但你一定了解「科学记数法」。

10进制科学记数法把一个数表示成a与10的n次幂相乘的形式(1≤|a|<10,a不为分数形式,n为整数),例如:

19970000000000 = 1.997 × 10 ^ 13

原本的 19970000000000 表示共需要14位。使用科学计数法后,小数部分 1.997 的表示需要4位,指数部分 13 需要2位,则一共只需要 4+2 = 6 位即可表示这个原本看上去很多很长的数。

小数也可以使用科学计数法来表示,例如:

0.0000001586 = 1.586 × 10 ^ -7

原本的 0.0000001586 表示共需要11位。使用科学计数法后,小数部分 1.586 的表示需要4位,指数部分 -7 需要2位(符号位也占一位),则一共只需要 4+2 = 6 位即可表示该数。

设想我们现在设计了这么一种格式,它表示的是一种10进制的科学计数法。为了说明简单,我们不考虑指数为负数和数值为负数的情况。它一共有8位,每一位都由10进制数字0~9组成,前6位表示小数部分,后2位表示指数部分。例如:

数字 12345603 ,它表示的值是 1.23456 × 10 ^ 3 = 1234.56

数字 12345678 ,它表示的值是 1.23456 × 10 ^ 78 = (一个很大的数)

所以,当我们要表示或运算某个较大或较小且位数较多的数时,用科学记数法会更加方便。

在关于定点数的这篇文章《什么是定点数?》中,我们谈到了什么是「定点数」。简而言之,定点数就是小数点表示固定的数。那么对应的,「浮点数」是不是就是小数点不固定?是浮动的?

恭喜你答对了。

浮点数」一词,来自英文「float point number」,即「动小数」。和上面所说的科学计数法类似,它们的小数点位置都是浮动的。

和10进制的科学计数法一样,2进制数也可以表示成类似的形式,例如:

101.875(D) = 1100101.111(B) = 1.100101111 * 2^6

所以只需要约定好一定的位数来表示小数部分,一定的位数来表示指数部分,就可以完整地表示一个二进制数。如何定义这些细节是个伤脑筋的问题,而且要命的是,如果我定义的标准和同事的标准不一致,那么该听谁的?

好在IEEE(电气与电子工程师协会,Institute of Electrical and Electronics Engineers)帮我们把这些工作都给做了,现在通用的浮点数算术标准是「IEEE 754」。

浮点数格式

IEEE 754 规定了两种常用的浮点数格式:

  • 单精度型,也叫32位型,或者float
  • 双精度型,也叫64位型,或者double

因为这两种格式的表示规则是类似的,只是位宽不一样,了解了其中一种后,就可以快速掌握另一种,所以下文主要介绍 float 类型的浮点数表示方法。

float类型

float 占用 32 位的存储空间,32 位被分为了如下的三个部分:

  • 符号位s:sign,符号位为 0 说明该浮点数为正数,若为 1 则说明浮点数为负数
  • 阶码E:exponent,代表该浮点数被二进制科学表示法规范化后的指数,阶码采用移码表示
  • 尾数M:mantissa,被二进制规约化后要求小数点前一位数必须为 1,所以尾数中实际隐含了最高位 1,例如尾数为 M,则实际在还原时,相当于是 1.M

(1)关于尾数M

尾数是用来表示精度的,因为一个数的表示其实是有多种方法的,例如:

314(D) = 3.14 × 10 ^ 2 = 31.4 × 10 ^ 1

1011(B) = 1.011 × 2 ^ 3 = 10.11 × 2 ^ 2 = 101.1 × 2 ^ 1

所以需要对小数部分的表示做出规定,为此标准规定小数部分需要简化到「小数点左边只有一位非0数」的形式。即规定:

314(D) 只能表示为 3.14 × 10 ^ 2 ,而不能表示为 31.4 × 10 ^ 1 或其他形式

1011(B) 只能表示为 1.011 × 2 ^ 3 ,而不能表示为 10.11 × 2 ^ 2,也不能表示为 101.1 × 2 ^ 1 或其他形式

因为10进制的非0数有1~9共9个,所以小数点最左边这位是不能省略掉的;但是2进制数的非0数只有1这个,所以小数点最左边的非0位可以被省略,例如:

1011(B) = 1.011 × 2 ^ 3 ,小数部分虽然为1.011,但是可以省略为.011,即011

这样就可以多表示一位信息。float的尾部部分(即小数部分)定义了23位,因为省略了一个最前面的 1 ,所以它是表示的其实是24位信息。

(2)关于阶码E

阶码是用来表示范围的。float定义了8位数的阶码,所以它的表示范围是0~256(2的256次方)。这种定义有个问题就是无法表示负指数,将其定义为有符号数是个不错的解决办法,但随之而来的问题是–比较两个阶码时不方便。

做两个有符号数的某些运算(例如加法)时,首先需要比较二者的阶码大小,然后对其中一个数的阶码和尾数进行调整。例如:

计算 (3.14 × 10 ^ 2) + (1.56 × 10 ^ 3)的值时,首先需要比较二者的阶码大小,然后对其中一个数进行调整,将(1.56 × 10 ^ 3)重新表示为(15.6 × 10 ^ 2),然后尾数部分相加 3.14 + 15.6 = 15.914,即结果为15.914 × 10 ^ 3,再调整阶码将其规范化,15.914 × 10 ^ 3 = 1.5914 × 10 ^ 4

可以看到,运算其中一个重要的环节就是对两个数的阶码大小进行对比。如果2个阶码是一正一负,那么对比二者的大小还需要考虑符号位,这样就会增加额外逻辑。如果将阶码都加上同一个数,使二者均为正数,那么对比大小就方便很多了。

标准是这样规定的:阶码的值需要加一个偏移量 127 (至于为什么移127不移128,我也不清楚,如果你知道可以告诉我)。例如:

1.011 × 2 ^ 3的原始阶码是3,按规定加上127后等于130,存储到8位空间,即为 1000 0010

光说不练云玩家,接下来看看如何实现浮点数与10进制数之间的转换。

(1)将10进制数转换为float类型的浮点数

228 转换为浮点数的流程如下:

  1. 是正数,即符号位为0
  2. 把10进制转成2进制:228(D)=11100100(B)
  3. 写成规范化形式:11100100 = 1.11001 × 2 ^ 7
  4. 指数为7,阶码要加上偏移量127,即E = 7 + 127 = 134(D)= 1000 0110(B)
  5. 小数部分为1.11001,最前面的1是可以被隐含表示的,所以尾数M = 0.11001 = 11001,因为尾数一共有23位,所以需要在低位补0直到满足位宽要求,即 11001000000000000000000

最终结果为:0 10000110 11001000000000000000000

image-20240408135855707

这里有一个浮点数转换网站,可以查询正确结果。

image-20240408135717205

(2)将float类型的浮点数转换为10进制数

40490000 (16进制)转换为10进制数的流程如下:

  1. 将其转换为2进制,40490000 = 0100 0000 0100 1001 0000 0000 0000 0000,然后分别获取符号、阶码和尾数。
  2. 最高位的符号位为0,说明是一个正数
  3. 接下来的8位是阶码 10000000(即128),因为加上了偏移量127,所以指数的实际值是128 - 127 = 1。
  4. 剩余的23位是尾数10010010000000000000000,即0.1001001,再加上默认的前导1,所以小数部分的值为1+0.1001001 = 1.1001001
  5. 该数的2进制值为 1.1001001 × 2 ^ 1 = 11.001001,将其转化成10进制数11.001001(B)= 3. 140625。(这里的转化有个简便方法,11.001001可以看做是11001001除以2的6次方即64,而11001001也就是201,即201/64 = 3.140625 )

这是网站转换的结果,和我们换算的结果一致。

image-20240408141627440

double类型

double占用 64 位的存储空间,64 位被分为了如下的三个部分:

71b0e30c8863b53edf8270fa1d5f1efe_062d155f612945cfbbf8b6943b9b10c7

这三部分的定义是和float类型一致的,只是位宽不同。需要注意的是,由于位宽的变化,所以double的阶码的偏移值不再是127,而是 1023

除了这两种较为常用的类型外,其实IEEE754还规定了几种其他类型,但是都不太常用,所以不赘述了。

非规约化

当阶码E不全为0,也不全为1时,该浮点数称为**规约化(normal)形式。上面介绍的都是规约化形式的浮点数。当阶码E全为0时,该浮点数称为非规约化(subnormal)**形式。根据尾数的不同,可再分为2种形式:

  • 尾数M为全 0 时,表示 0 ,视符号位而定是+0还是-0(二者在某些场景有区别)
  • 尾数M不全为 0 时,表示非规约化小数

非规约化小数的定义和规约化小数之间存在如下区别:

  • 规约化小数的尾数约定了含有一个隐藏的前导1,也就说真正表示的值是1.xxx;而非规约化小数的尾数则约定含有一个隐藏的前导0,即真正的值为0.xxx。
  • 规约化小数的阶码需要加一个偏移量127,而非规约化小数的阶码需要加一个偏移量 126

非规约化小数可以用来表示那些非常小的接近0的数。

特殊值

除此之外,还规定了一些特殊值的表示方法:

  • 如果阶码为全1,且尾数为全0时,表示无穷。符号位为0则是正无穷,符号位为1则是负无穷。两个很大的数相乘,或者除以零时,无穷可以表示 溢出 的结果。
  • 如果阶码为全1,且尾数不为全0时,为NaN(not a number),表示这不是一个合法实数。一些运算的结果不是合法值,就会返回NaN这样的结果,例如对-1开平方(√-1)

对于以上情况(针对float类型),可以总结如下:

image-20240408145444454

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1634892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关系(五)利用python绘制连接散点图

关系&#xff08;五&#xff09;利用python绘制连接散点图 连接散点图&#xff08;Connected Scatterplot&#xff09;简介 连接散点图&#xff08;点线图&#xff09;是折线图的一种&#xff0c;与散点图类似。但添加了按数据点出现顺序的连线&#xff0c;以此来表示两个变量…

币圈Cryptosquare论坛

Cryptosquare综合性资讯论坛汇集了币圈新闻、空投信息、社会热点以及与Web3相关的工作信息。让我们一起解锁加密世界的种种可能性&#xff0c;探索Cryptosquare论坛带来的精彩&#xff01; 币圈新闻板块&#xff1a; Cryptosquare论坛的币圈新闻板块是用户获取最新加密货币行业…

vite打包配置

目录 minify默认是esbuild&#xff0c;不能启动下面配置 使用&#xff1a; plugins: [viteMockServe({mockPath: mock})]根目录新建mock/index.ts. 有例子Mock file examples&#xff1a;https://www.npmjs.com/package/vite-plugin-mock-server 开发环境生产环境地址替换。根…

Matlab|含sop的33节点配电网优化

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 程序以IEEE33节点为例&#xff0c;分析含sop的配电网优化&#xff0c;包括sop有功约束、无功约束和容量约束&#xff0c;非线性部分通过转换为旋转锥约束进行编程&#xff0c;并且包括33节点配电网潮流及对应…

python自动化操作docx

使用Python自动化处理Word文档 在日常工作中&#xff0c;我们经常需要处理大量的Word文档&#xff0c;这时自动化脚本就显得尤为重要。本文将介绍如何使用Python中的python-docx库来创建和修改Word文档。 安装python-docx库 在开始之前&#xff0c;确保你已经安装了python-d…

基于JWT实现的Token认证方案

JSON Web Token是什么&#xff1f; JSON Web Token&#xff08;JWT&#xff09;是目前最流行的跨域身份验证解决方案。 JSON Web Token&#xff08;JWT&#xff09;是一个开放标准&#xff08;RFC 7519&#xff09;&#xff0c;它定义了一种紧凑且自包含的方式&#xff0c;用…

电脑文件误删除如何恢复?这5个策略亲测有效!

“求助&#xff01;在电脑上不小心删除了文件还有机会找回来吗&#xff1f;一不小心我就删除了一个重要的工作文件&#xff01;大家快帮帮我吧&#xff01;” 保存在电脑里的文件对电脑用户来说很多都是非常重要的&#xff0c;我们可能生活中、学习上以及工作上都需要使用这些文…

C++学习第七课:控制程序流程的学习和示例详解

C学习第七课&#xff1a;控制程序流程 在C中&#xff0c;控制程序流程是编程逻辑的核心部分&#xff0c;它决定了程序的执行顺序。本课我们将介绍C中的各种控制流程语句&#xff0c;包括条件语句、循环语句以及如何使用它们遍历多维数组和计算斐波那契数列。 控制流程语句 i…

哪个牌子的骨传导耳机好用?盘点五款高热度爆款骨传导耳机推荐!

近年来&#xff0c;骨传导耳机在潮流的推动下销量节节攀升&#xff0c;逐渐成为运动爱好者和音乐迷们的必备装备。但热度增长的同时也带来了一些品质上的忧患&#xff0c;目前市面上的部分产品&#xff0c;存在佩戴不舒适、音质不佳等问题&#xff0c;甚至可能对听力造成潜在损…

VSCode SSH连接远程主机失败,显示Server status check failed - waiting and retrying

vscode ssh连接远程主机突然连接不上了&#xff0c;终端中显示&#xff1a;Server status check failed - waiting and retrying 但是我用Xshell都可以连接成功&#xff0c;所以不是远程主机的问题&#xff0c;问题出在本地vscode&#xff1b; 现象一&#xff1a; 不停地输入…

Python俄罗斯方块

文章目录 游戏实现思路1. 游戏元素的定义2. 游戏区域和状态的定义3. 游戏逻辑的实现4. 游戏界面的绘制5. 游戏事件的处理6. 游戏循环7. 完整实现代码 游戏实现思路 这个游戏的实现思路主要分为以下几个步骤&#xff1a; 1. 游戏元素的定义 Brick类&#xff1a;表示游戏中的砖…

使用Tortoise 创建远程分支

1。首先创建本地分支branch1&#xff0c;右键tortoise git->创建分支&#xff0c;输入分支名称branch1&#xff0c;确定。 2。右键tortoise git->推送&#xff0c;按下图设置&#xff0c;确定&#xff0c;git会判断远程有没有分支branch1&#xff0c;如果没有会自动创建…

QT类之间主窗口子窗口传递*指针对象

1.新建CFile_Operation 类文件 2.主窗口头文件声明&#xff1a; CFile_Operation *cfile_operation; 按钮点击事件函数里面调用子窗口 dialog_debug new Dialog_Debug(this);connect(this,&MainWindow_oq::SendCfile_operation_Obj,dialog_debug,&Dialog_Debug::R…

【redis】初始redis和分布式系统的基本知识

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

Linux中ssh登录协议

目录 一.ssh基础 1.ssh协议介绍 2.ssh协议的优点 3.ssh文件位置 二.ssh原理 1.公钥传输原理&#xff08;首次连接&#xff09; 2.ssh加密通讯原理 &#xff08;1&#xff09;对称加密 &#xff08;2&#xff09;非对称加密 3.远程登录 三.服务端的配置 常用的配置项…

C++信息学奥赛 数据结构认识

数据结构 1.1数据结构分类 1.2基本数据类型 1.3数字编码 1.4字符编码 1.1数据结构分类 数据结构如同一副稳固而多样的框架。为数据的有序组织提供了蓝图&#xff0c;算法得以在此基础上生动起来。 常用的数据结构包括哪些 &#xff0c; &#xff0c; &…

QA测试开发工程师面试题满分问答21: 单元测试、集成测试、系统测试的侧重点是什么?

单元测试、集成测试和系统测试是软件测试中的不同层次和阶段&#xff0c;每个阶段侧重于不同的测试目标和范围。以下是它们的侧重点的简要说明&#xff1a; 单元测试&#xff1a; 单元测试是针对软件中最小的可测试单元&#xff08;通常是函数、方法或模块&#xff09;进行的测…

版本控制系统-Git

目录 1. Git简介 2. 下载及安装 3.命令行操做 3.1全局设置 3.2初始化仓库 3.3提交代码 3.4查看提交历史 3.5推送代码 3.6拉取合并代码 3.7克隆仓库 3.8. 配置忽略文件 3.9. 凭据管理 4. GUI工具操作 4.1. 全局设置 4.2. 初始化仓库 4.3. 提交代码 输入提交日志…

Gone框架介绍3 - 使用gone命令,自动生成Priest函数

文章目录 1. 安装辅助工具: gone2. 创建一个名为gen-code的新项目3. 创建Goner4. 使用辅助工具5. 添加main函数 我在两年前实现了一个Golang的依赖注入框架&#xff0c;并且集成了gin、xorm、redis、cron、消息中间件等功能&#xff0c;自己觉得还挺好用的&#xff1b;之前一直…

Jenkins首次Build,配置Git,Maven,JDK,凭证管理

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudso…