开发必备知识:浮点数的工作原理与使用注意事项

什么是浮点数?

浮点数是相对定点数而言的,我们先把这两个概念搞清楚。

定点数和浮点数都是用于表示数值的格式,它们的主要区别在于如何表示小数部分,也就是如何处理小数点的问题。

定点数是将一个数的整数部分和小数部分用固定的位数来表示,小数点的位置是固定的。这里的"定点"是指小数点的位置是固定不变的,注意不是说这个数一定要有小数部分。例如:我们有一个四位的定点数1234,约定前两位表示整数部分,后两位表示小数部分,那么这个数就代表12.34。

浮点数则是一种更复杂的数值表示方法,其中小数点的位置是可以变动的。它由三部分组成:符号位、指数部分和尾数部分。以单精度浮点数为例,它占用4字节,其中1位是符号位,8位是指数部分,23位是尾数部分。例如,我们可以将数字123.45表示为1.2345乘以10的2次方,这就是一个浮点数。如果你了解过科学计数法,可以看到浮点数就是使用的科学计数法。

为什么需要浮点数?

定点数对比浮点数,表示相同数字的时候,定点数可能使用更多的存储空间。例如,在BCD编码中,1个数字需要4bit表示,这意味着32位只能表示1亿个数,再大的数字就需要更多的bit来表示。

其次,定点数无法同时表示很大的数字和很小的数字。假设我们用一个16位的定点数来表示数值,其中8位用于表示整数部分,8位用于表示小数部分。

  • 此时能表示的最大数就是255.996(即二进制的11111111.11111111)。那么,如果我们需要表示一个比这个数大的数,例如300,就无法用这个16位的定点数来表示了。
  • 对于较小的数字,由于小数部分只有8位,最小能表示的数是1/(2^8)=0.0039(即二进制的0.00000001)。因此,这个16位的定点数也无法表示0.0001这样的小数。

因此,浮点数应运而生,作为一种更有效的处理小数的方法。浮点数的优点是可以表示非常大或非常小的数,而且可以保持相对较高的精度,但是计算速度相对较慢。

浮点数标准

在科学计算中,我们通常使用IEEE 754标准来表示小数,这是一种浮点数表示和运算的标准,是现代计算机中处理浮点数的基础。在这个标准中:

数字它由符号位、指数位和尾数位三部分组成。符号位决定了浮点数的正负,指数位决定了浮点数的大小,尾数位则决定了浮点数的精度。

单精度浮点数可以保证6-7位十进制有效数字,取值范围是10的-38次方到10的38次方,占用4字节空间,包括符号位1位,阶码8位,尾数23位。

双精度浮点数则可以保证15-16位十进制有效数字,取值范围是10的-308次方到10的308次方,占用8字节空间,包括符号位1位,阶码11位,尾数52位。

精度损失问题

我们在上面说的有效数字为什么不是固定的7位或者16位?

这是因为计算机采用二进制系统,有些十进制小数无法被二进制精确表示,这就可能导致精度降低。比如,0.1在二进制中是一个无限循环小数,所以在计算机中,无论是单精度还是双精度,都无法精确地表示0.1,这就可能导致精度降低。

附带介绍下十进制小数转二进制的方法:不断地将小数位乘以2,如果结果小于1就取0,如果结果大于1就取1,然后再减去1,然后继续这个过程。

如果小数位是无限非0循环,我们就会因为只能记录最大有效位而导致精度丢失。而在进行加法运算时,我们需要先对齐,再计算。如果两个数的指数位相差较大,我们就需要将指数位较小的数通过有效位右移的方式进行对齐,这样就会损失一部分有效位的数据,从而导致精度损失。

精确数值方法

那么,有没有不丢失精度的方法来表示小数呢?答案是肯定的。首先,我们可以使用定点数,通过BCD编码,每个数字用4bit表示,左边x位bit表示整数,右边y位bit表示小数,比如很多开发语言中都有的decimal数据类型。另外,我们也可以使用整数类型,比如金额可以用分来表示,例如100.45元可以转换为10045分,这样就可以避免精度损失。

总结

浮点数是一种非常有效的表示小数的方法,虽然它在处理某些情况时会有精度损失的问题,但是我们可以通过适当的方式来避免这种情况的发生。作为开发人员,我们需要了解浮点数的工作原理和使用注意事项,这样才能保证程序的健壮性。

更多学习资源

我注册了一个微/信/公/众/号:萤火架构,后续会分享很多架构方面的经验和认识,欢迎关注,以免错过精彩内容。

最后用一幅图做个总结,如需高清大图请关注公众号后获取。

相关推荐
小尤笔记4 天前
Python操作系统的6个自动化脚本
数据库·python·自动化·php·编程语言·python入门
神经星星9 天前
【TVM 教程】使用 Relay Visualizer 可视化 Relay
人工智能·机器学习·编程语言
GoppViper20 天前
golang学习笔记17——golang使用go-kit框架搭建微服务详解
笔记·后端·学习·微服务·golang·编程语言·go-kit
GoppViper23 天前
golang学习笔记12——Go 语言内存管理详解
笔记·后端·学习·golang·编程语言·内存优化·golang内存管理
GoppViper24 天前
golang学习笔记11——Go 语言的并发与同步实现详解
笔记·后端·学习·golang·编程语言·goroutine·golang并发
一丝晨光24 天前
安全API
java·开发语言·c++·安全·编程·c·编程语言
GoppViper25 天前
golang学习笔记15——golang依赖管理方法
笔记·后端·学习·golang·编程语言·源代码管理·golang依赖管理
GoppViper1 个月前
golang学习笔记10——golang 的 Gin 框架,快速构建高效 Web 应用
笔记·学习·golang·gin·编程语言
Geektec1 个月前
智能代码编辑器:Visual Studio Code的深度剖析
vscode·编辑器·编程·代码编辑器·编程语言
股票程序交易接口1 个月前
更适合编写股票盯盘软件或者量化交易平台的语言是Python还是C
量化交易·编程语言·股票api接口·股票量化接口·python股票接口