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

什么是浮点数?

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

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

定点数是将一个数的整数部分和小数部分用固定的位数来表示,小数点的位置是固定的。这里的"定点"是指小数点的位置是固定不变的,注意不是说这个数一定要有小数部分。例如:我们有一个四位的定点数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分,这样就可以避免精度损失。

总结

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

更多学习资源

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

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

相关推荐
数据智能老司机1 天前
Rust原子和锁——Rust 并发基础
性能优化·rust·编程语言
数据智能老司机2 天前
Rust中的异步编程——创建我们自己的Fiber
性能优化·rust·编程语言
微刻时光5 天前
程序员开发速查表
java·开发语言·python·docker·go·php·编程语言
咕噜Yuki06098 天前
Java基础篇:学会这些技能,程序员职场竞争力UP UP
java·开发语言·编程语言
codeGoogle8 天前
计算机书籍打包
前端·后端·编程语言
Moonbit10 天前
MoonBit 双周报 Vol.59:新增编译器常量支持,改进未使用警告,支持跨包函数导入...多个关键技术持续优化中!
编程语言
神经星星10 天前
【TVM 教程】外部张量函数
人工智能·开源·编程语言
Moonbit13 天前
MGPIC案例分享|零基础早鸟教程:8小时使用 wasm4 开发井子棋小游戏!
编程语言
邓校长的编程课堂16 天前
少儿编程进入义务教育课程:培养信息科技素养的新政策解读
科技·编程语言·少儿编程·信息学竞赛·科技特长生·义务教育
Moonbit23 天前
MoonBit 双周报 Vol.58:原生后端支持、多行字符串插值、json.inspect 功能等多项关键特性取得显著进展!
编程语言