15张图带你深入理解浮点数

您所在的位置:网站首页 浮点数的精度和范围取决于 15张图带你深入理解浮点数

15张图带你深入理解浮点数

2024-07-12 22:37| 来源: 网络整理| 查看: 265

本着「要学习就系统透彻的学」这个原则,本文通过图的方式尽可能详细的讲解浮点数,让大家能够对浮点数有一个更深层次的认识。

本文目录:

 

0、几个问题

开始之前请思考如下问题:

二进制 0.1,用十进制表示的话是多少?十进制的 0.1,用二进制表示又是多少? 为什么 0.1 + 0.2 = 0.30000000000000004? 单精度和双精度浮点数的有效小数位分别是多少? 单精度浮点数能表示的范围是什么? 浮点数为什么会存在 -0?infinity 和 NaN 又是怎么表示的?

如果现在不会,那这篇文章正好可以为你解惑

1、什么是浮点数

我们知道,数学中并没有浮点数的概念,虽然小数看起来像浮点数,但从不这么叫。那为什么计算机中不叫小数而叫浮点数呢?

因为资源的限制,数学中的小数无法直接在计算机中准确表示。为了更好地表示它,计算机科学家们发明了浮点数,这是对小数的近似表示。

也就是说浮点数是相对于定点数而言的,表示小数点位置是浮动的。比如 7.5 × 10、0.75 × 10² 等表示法,值一样,但小数点位置不一样。

具体来说,浮点数是指用符号、尾数、基数和指数这四部分来表示的小数。

2、IEEE754 又是什么

知道了浮点数的概念,但需要确定一套具体的表示、运算标准。其中最有名的就是 IEEE754 标准 。William Kahan 正是因为浮点数标准化的工作获得了图灵奖。

本文的讨论都基于 IEEE754 标准,这也是目前各大编程语言和硬件使用的标准。

根据上面浮点数的组成,因为是在计算机中表示浮点数,基数自然是 2,因此 IEEE754 浮点数只关注符号、尾数和指数三部分。

3、小数的二进制和十进制转换

为了方便后面的内容顺利进行,复习下二进制和十进制的转换,其中主要涉及到小数的转换。

二进制转十进制

和整数转换一样,采用各位数值和位权相乘。比如:

(0.101)₂ = 1×2⁻¹ + 0×2⁻² + 0×2⁻³ = (0.625)₁₀

记住小数点后第一位是从 -1 开始即可。

十进制转二进制

十进制整数转二进制采用“除 2 取余,逆序排列”法。例如十进制数 11 转为二进制:

所以 (11)₁₀ 的二进制是 (1011)₂。

但如果十进制是小数,转为二进制小数如何做?采用“乘 2 取整,顺序排列”。例如十进制小数 0.625 转为二进制小数:

顺序排列,所以 (0.625)₁₀ = (0.101)₂。

为了方便大家快速的做转换,网上有很多这样的工具。推荐一个我觉得最棒的:https://baseconvert.com/,支持各进制的转换,还支持浮点数。

4、经典问题:0.1 + 0.2 = 0.30000000000000004

这个问题网上相关的讨论很多,甚至有专门的一个网站:https://0.30000000000000004.com/,这个网站上有各门语言的 0.1 + 0.2 的结果。比如 C 语言:

 Go 语言:

结果都是 0.30000000000000004。

为什么会这样?这要回到 IEEE754 标准关于浮点数的规定。

5、浮点数的 IEEE754 表示

上文提到,浮点数由四个部分构成,那 IEEE754 标准是如何规定它们的存储方式的呢?

一般地,IEEE754 浮点数有两种类型:单精度浮点数(float)和双精度浮点数(double),还有其他的,不常用。单精度浮点数使用 4 字节表示;双精度浮点数使用 8 字节表示。在 Go 语言中用 float32 和 float64 表示这两种类型。

 符号位不用说,0 表示正数,1 表示负数。着重看指数部分和尾数部分。(基数前文说了,固定是 2,因此不存)

尾数部分

前面提到过,浮点数名称的由来在于小数点是浮动的。但具体存储时,需要固定一种形式,这叫做尾数的标准化。IEEE754 规定,在二进制数中,通过移位,将小数点前面的值固定为 1。IEEE754 称这种形式的浮点数为规范化浮点数(normal number)。

比如十进制数 0.15625,转为二进制是 0.00101。为了让第 1 位为 1,执行逻辑右移 3 位,尾数部分成为 1.01,因为右移了 3 位,所以指数部分是 -3。因为规定第 1 位永远为 1,因此可以省略不存,这样尾数部分多了 1 位,只需存 0100(要记住,这是的数字是小数点后的数字,因此实际是 0.01,转为十进制是 0.25 — 没算未存的小数点前面的 1)。

因此对于规范化浮点数,尾数其实比实际的多 1 位,也就是说单精度的是 24 位,双精度是 53 位。为了作区分,IEEE754 称这种尾数为 significand。

有规范化浮点数,自然会有非规范化浮点数(denormal number),这会在后文讲解。

请牢记,尾数决定了精度,对于单精度浮点数,因为只有 23 位,而 1



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3