什么是浮点数?

article/2025/9/9 21:45:12

微信搜索关注「水滴与银弹」公众号,第一时间获取优质技术干货。7年资深后端研发,用简单的方式把技术讲清楚。

在上一篇文章中,我们主要介绍了在计算机中使用定点数表示数字的方式。

简单回顾一下,简单来说,用定点数表示数字时,会约定小数点的位置固定不变,整数部分和小数部分分别转换为二进制,就是定点数的结果。

但用定点数表示小数时,存在数值范围、精度范围有限的缺点,所以在计算机中,我们一般使用「浮点数」来表示小数。

这篇文章,我们就来详细看一下浮点数到底是如何表示小数的,以及浮点数的的范围和精度有多大。

什么是浮点数?

首先,我们需要理解什么是浮点数?

之前我们学习了定点数,其中「定点」指的是约定小数点位置固定不变。那浮点数的「浮点」就是指,其小数点的位置是可以是漂浮不定的。

这怎么理解呢?

其实,浮点数是采用科学计数法的方式来表示的,例如十进制小数 8.345,用科学计数法表示,可以有多种方式:

8.345 = 8.345 * 10^0
8.345 = 83.45 * 10^-1
8.345 = 834.5 * 10^-2
...

看到了吗?用这种科学计数法的方式表示小数时,小数点的位置就变得「漂浮不定」了,这就是相对于定点数,浮点数名字的由来。

使用同样的规则,对于二进制数,我们也可以用科学计数法表示,也就是说把基数 10 换成 2 即可。

浮点数如何表示数字?

我们已经知道,浮点数是采用科学计数法来表示一个数字的,它的格式可以写成这样:

V = (-1)^S * M * R^E

其中各个变量的含义如下:

  • S:符号位,取值 0 或 1,决定一个数字的符号,0 表示正,1 表示负
  • M:尾数,用小数表示,例如前面所看到的 8.345 * 10^0,8.345 就是尾数
  • R:基数,表示十进制数 R 就是 10,表示二进制数 R 就是 2
  • E:指数,用整数表示,例如前面看到的 10^-1,-1 即是指数

如果我们要在计算机中,用浮点数表示一个数字,只需要确认这几个变量即可。

假设现在我们用 32 bit 表示一个浮点数,把以上变量按照一定规则,填充到这些 bit 上就可以了:

在这里插入图片描述

假设我们定义如下规则来填充这些 bit:

  • 符号位 S 占 1 bit
  • 指数 E 占 10 bit
  • 尾数 M 占 21 bit

按照这个规则,将十进制数 25.125 转换为浮点数,转换过程就是这样的(D代表十进制,B代表二进制):

  1. 整数部分:25(D) = 11001(B)
  2. 小数部分:0.125(D) = 0.001(B)
  3. 用二进制科学计数法表示:25.125(D) = 11001.001(B) = 1.1001001 * 2^4(B)

所以符号位 S = 0,尾数 M = 1.001001(B),指数 E = 4(D) = 100(B)。

按照上面定义的规则,填充到 32 bit 上,就是这样:
在这里插入图片描述
浮点数的结果就出来了,是不是很简单?

但这里有个问题,我们刚才定义的规则,符号位 S 占 1 bit,指数位 E 占 10 bit,尾数 M 占 21 bit,这个规则是我们拍脑袋随便定义出来的。

如果你也想定一个新规则,例如符号位 S 占 1 bit,指数位 E 这次占 5 bit,尾数 M 占 25 bit,是否也可以?当然可以。

按这个规则来,那浮点数表示出来就是这样:
在这里插入图片描述
我们可以看到,指数和尾数分配的位数不同,会产生以下情况:

  1. 指数位越多,尾数位则越少,其表示的范围越大,但精度就会变差,反之,指数位越少,尾数位则越多,表示的范围越小,但精度就会变好
  2. 一个数字的浮点数格式,会因为定义的规则不同,得到的结果也不同,表示的范围和精度也有差异

早期人们提出浮点数定义时,就是这样的情况,当时有很多计算机厂商,例如IBM、微软等,每个计算机厂商会定义自己的浮点数规则,不同厂商对同一个数表示出的浮点数是不一样的。

这就会导致,一个程序在不同厂商下的计算机中做浮点数运算时,需要先转换成这个厂商规定的浮点数格式,才能再计算,这也必然加重了计算的成本。

那怎么解决这个问题呢?业界迫切需要一个统一的浮点数标准。

浮点数标准

直到1985年,IEEE 组织推出了浮点数标准,就是我们经常听到的 IEEE754 浮点数标准,这个标准统一了浮点数的表示形式,并提供了 2 种浮点格式:

  • 单精度浮点数 float:32 位,符号位 S 占 1 bit,指数 E 占 8 bit,尾数 M 占 23 bit
  • 双精度浮点数 float:64 位,符号位 S 占 1 bit,指数 E 占 11 bit,尾数 M 占 52 bit

为了使其表示的数字范围、精度最大化,浮点数标准还对指数和尾数进行了规定:

  1. 尾数 M 的第一位总是 1(因为 1 <= M < 2),因此这个 1 可以省略不写,它是个隐藏位,这样单精度 23 位尾数可以表示了 24 位有效数字,双精度 52 位尾数可以表示 53 位有效数字
  2. 指数 E 是个无符号整数,表示 float 时,一共占 8 bit,所以它的取值范围为 0 ~ 255。但因为指数可以是负的,所以规定在存入 E 时在它原本的值加上一个中间数 127,这样 E 的取值范围为 -127 ~ 128。表示 double 时,一共占 11 bit,存入 E 时加上中间数 1023,这样取值范围为 -1023 ~ 1024。

除了规定尾数和指数位,还做了以下规定:

  • 指数 E 非全 0 且非全 1:规格化数字,按上面的规则正常计算
  • 指数 E 全 0,尾数非 0:非规格化数,尾数隐藏位不再是 1,而是 0(M = 0.xxxxx),这样可以表示 0 和很小的数
  • 指数 E 全 1,尾数全 0:正无穷大/负无穷大(正负取决于 S 符号位)
  • 指数 E 全 1,尾数非 0:NaN(Not a Number)
    在这里插入图片描述

标准浮点数的表示

有了这个统一的浮点数标准,我们再把 25.125 转换为标准的 float 浮点数:

  1. 整数部分:25(D) = 11001(B)
  2. 小数部分:0.125(D) = 0.001(B)
  3. 用二进制科学计数法表示:25.125(D) = 11001.001(B) = 1.1001001 * 2^4(B)

所以 S = 0,尾数 M = 1.001001 = 001001(去掉1,隐藏位),指数 E = 4 + 127(中间数) = 135(D) = 10000111(B)。填充到 32 bit 中,如下:
在这里插入图片描述

这就是标准 32 位浮点数的结果。

如果用 double 表示,和这个规则类似,指数位 E 用 11 bit 填充,尾数位 M 用 52 bit 填充即可。

浮点数为什么有精度损失?

我们再来看一下,平时经常听到的浮点数会有精度损失的情况是怎么回事?

如果我们现在想用浮点数表示 0.2,它的结果会是多少呢?

0.2 转换为二进制数的过程为,不断乘以 2,直到不存在小数为止,在这个计算过程中,得到的整数部分从上到下排列就是二进制的结果。

0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(发生循环)
...

所以 0.2(D) = 0.00110…(B)。

因为十进制的 0.2 无法精确转换成二进制小数,而计算机在表示一个数字时,宽度是有限的,无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度发生损失的情况。

浮点数的范围和精度有多大?

最后,我们再来看一下,用浮点数表示一个数字,其范围和精度能有多大?

以单精度浮点数 float 为例,它能表示的最大二进制数为 +1.1.11111…1 * 2^127(小数点后23个1),而二进制 1.11111…1 ≈ 2,所以 float 能表示的最大数为 2^128 = 3.4 * 10^38,即 float 的表示范围为:-3.4 * 10^38 ~ 3.4 * 10 ^38。

它能表示的精度有多小呢?

float 能表示的最小二进制数为 0.0000…1(小数点后22个0,1个1),用十进制数表示就是 1/2^23。

用同样的方法可以算出,double 能表示的最大二进制数为 +1.111…111(小数点后52个1) * 2^1023 ≈ 2^1024 = 1.79 * 10^308,所以 double 能表示范围为:-1.79 * 10^308 ~ +1.79 * 10^308。

double 的最小精度为:0.0000…1(51个0,1个1),用十进制表示就是 1/2^52。

从这里可以看出,虽然浮点数的范围和精度也有限,但其范围和精度都已非常之大,所以在计算机中,对于小数的表示我们通常会使用浮点数来存储。

总结

这篇文章我们主要讲了数字的浮点数表示方式,总结如下:

  1. 浮点数一般用科学计数法表示
  2. 把科学计数法中的变量,填充到固定 bit 中,即是浮点数的结果
  3. 在浮点数提出的早期,各个计算机厂商各自制定自己的浮点数规则,导致不同厂商对于同一个数字的浮点数表示各不相同,在计算时还需要先进行转换才能进行计算
  4. 后来 IEEE 组织提出了浮点数的标准,统一了浮点数的格式,并规定了单精度浮点数 float 和双精度浮点数 double,从此以后各个计算机厂商统一了浮点数的格式,一直延续至今
  5. 浮点数在表示小数时,由于十进制小数在转换为二进制时,存在无法精确转换的情况,而在固定 bit 的计算机中存储时会被截断,所以浮点数表示小数可能存在精度损失
  6. 浮点数在表示一个数字时,其范围和精度非常大,所以我们平时使用的小数,在计算机中通常用浮点数来存储

微信搜索关注「水滴与银弹」公众号,第一时间获取优质技术干货。7年资深后端研发,用简单的方式把技术讲清楚。


http://chatgpt.dhexx.cn/article/FgYJASJW.shtml

相关文章

浮点数加减运算

浮点运算要把阶码和尾数分别处理。 阶码的运算是定点整数运算&#xff0c;对阶码的运算四种&#xff1a;阶码加1&#xff0c;阶码减1&#xff0c;两阶码求和&#xff0c;两阶码求差。 尾数的运算是定点小数运算&#xff0c;运算过程中一般取双符号位 浮点运算器总是由处理阶…

浮点数运算原理详解

导读&#xff1a;浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题。 许多人使用float/double进行货币计算时经常会犯错。这篇文章是这一系列中的精华&#xff0c;所有的软件开发人员都应…

浮点数运算——加减乘除都有哈

什么是浮点数 浮点数运算异常 IEEE 754 标准规定的五种异常情况 浮点数除0的问题 浮点数加减运算 浮点数乘除运算 导读&#xff1a;浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题…

浮点数的运算步骤

浮点数的运算步骤 浮点数的加减运算一般由以下五个步骤完成&#xff1a;对阶、尾数运算、规格化、舍入处理、溢出判断 一、对阶 所谓对阶是指将两个进行运算的浮点数的阶码对齐的操作。对阶的目的是为使两个浮点数的尾数能够进行加减运算。因为&#xff0c;当进行M x2Ex与M …

浮点数运算

今天学习了浮点数运算&#xff08;加减乘除&#xff09;。浮点数运算主要包括两部分&#xff1a;指数运算和尾数运算。在IEEE754标准下&#xff0c;指数运算就是阶码的运算&#xff0c;类似于无符号数运算。尾数运算是原码运算。之前一直很疑惑为什么前面的教材在介绍原码运算&…

计算机组成原理:浮点数的加、减、乘、除运算(含实例完整运算)

目录 浮点数的加减运算 零操作数的判断 对阶操作 尾数的加减操作 尾数的规格化 结果的舍入处理 结果的溢出判断 加减实例运算过程 浮点数的乘除法 零操作数的检查 阶码的加减操作 尾数的乘除操作 结果的规格化、舍入处理及溢出的判断 具体的操作如下图 乘除实例运算…

浮点数的运算方法

浮点数的运算方法 一、浮点数的表示1.浮点数的表示2.IEEE 754标准3.浮点数类型 二、浮点数的加减法1.定义2.运算步骤 三、运算部件四、强化练习 一、浮点数的表示 1.浮点数的表示 Ms表示尾数的符号位&#xff0c;E中1bit保存阶码的符号位其余空间存放阶码值&#xff0c;M中存放…

typeScript 接口(interface)及其与类型别名(type)的区别

背景 最近自己在学习一些视频剪辑相关的工具&#xff0c;像爱剪辑&#xff0c;剪映这些软件。然后就想自己是不是也可以实现一个类似的&#xff0c;轻量级的在线剪辑工具。最后发现这个款node端的工具库FFCreator&#xff0c;接下来简单介绍一下如何来搭建开发环境&#xff0c…

Type Description : This type is a general type that can be used to declare

错误描述&#xff1a; Complex type: param-valueType Description : This type is a general type that can be used to declare parameter/value lists. 解决方法&#xff1a; 把0移到init-param下面

Type and Value

Type and Value 前言一、reflect.Type1.1 数据结构1.2 方法1.2.1 所有类型通用方法1.2.2 不同基础类型的专有方法 二、reflect.Value总结参考资料 前言 reflect.Type和reflect.Value是go 反射的两大基本类型&#xff0c;一个管变量的类型方面&#xff0c;一个管变量的值方面。…

typescript interface 与 type 声明类型的区别

在 typescript 中, 我们定义类型有两种方式&#xff1a; 接口(interface) 和类型别名(type alias) 在官方文档中我们可以看到: Unlike an interface declaration, which always introduces a named object type, a type alias declaration can introduce a name for any kind…

type是什么

作者&#xff1a;newis 链接&#xff1a;https://www.zhihu.com/question/376890141/answer/1302417252 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 程语言的Type的话&#xff0c;有在不同的场景下有不同的意义…

Type-C

一、Type-C 从USB TYPE-C 的Spec上截一个USB TYPE-C母座的pin脚图&#xff1a; 可以看出&#xff0c;母座上有24根信号&#xff0c; 其中电源和地占据了8根&#xff0c;用于提升电流传输能力&#xff0c;剩下16个&#xff1a; &#xff08;1&#xff09;传输USB3数据的RXx和…

Java Type

Type 是Java 编程语言中所有类型的公共高级接口&#xff08;官方解释&#xff09;&#xff0c;也就是Java 中所有类型的”爹“。其中”所有类型“的描述尤为指的关注。它并不是我们平常工作中经常使用的int、String、List、Map等数据类型&#xff0c;而是从Java语言角度磊说&am…

常见USB接口总结:Type-A、Mini-USB、Micro-USB、Type-C等等

写在前面 最近在整理之前的笔记&#xff0c;打算把一些有价值的笔记发到CSDN分享一下。这篇总结参考的链接如下&#xff0c;结合了自己找的一些图片&#xff0c;非原创&#xff0c;侵权的话私聊我删除。 参考文章链接 https://mb.zol.com.cn/514/5147157.html 总览 标准Type-…

# USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义

USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义 文章目录 USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义1 USB Type-A&#xff08;USB-A&#xff09;2 USB Type-B&#xff08;USB-B&#xff09;3 USB Type-C&#xff08;USB-C&#xff09;3.1 24Pin3.2 16Pi…

Java FileReader相对路径

实验一快要到DDL了&#xff0c;今天在用Javac和Java命令手动执行实验一的代码的时候发现一个问题&#xff0c;当时在IDEA中运行正常的代码&#xff0c;在javac编译手动用java执行的时候发现并不能通过&#xff0c;出问题的代码是一段&#xff08;试图&#xff09;使用相对路径来…

详解HTML的相对路径写法,详解URL相对路径的写法

虽然现在搭网站都会用各种框架&#xff0c;路径方面使用相对路径可能已经比较少了&#xff0c;不过还是总结一下吧。 假设D盘这个路径下有一些文件&#xff1a; D:\例子\html\images\ D:\例子\html\style\ D:\例子\html\example.html D:\例子\html\tupian.gif 1.若引用的资源和…

Python读取相对路径文件

例如下图目录结构: 第一种情况: 1)xxx.py想要打开a.txt,使用相对路径,有如下两种方式: 思路: xxx.py想打开的是b_file下的文件,XXX.py和b_file都在文件目录之下,两者是同级目录,因此操作就是在当前目录向下搜索,因此就可以很容易理解下面的意思了 特别提示:… \是错…

html 的相对路径和绝对路径

整篇文章是以 src 标签进行演示。 文章目录 一、相对路径 1、同级目录查找 2、上一级目录查找 3、下一级目录查找 二、绝对路径 一、相对路径 &#x1f475;相对路径&#xff1a;从当前所处的目录开始查找。 1、同级目录查找 写法&#xff1a; 1.1.直接写文件名&#xf…