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

什么是浮点数?

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

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

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

总结

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

更多学习资源

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

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

相关推荐
liulilittle3 天前
UNIX/macOS路由表查询原理与实现
服务器·开发语言·c++·macos·unix·编程语言
liulilittle3 天前
HTTP简易客户端实现
开发语言·网络·c++·网络协议·http·编程语言
liulilittle4 天前
Unix/Linux 平台通过 IP 地址获取接口名的 C++ 实现
linux·开发语言·c++·tcp/ip·unix·编程语言
hqyjzsb5 天前
2025职场进阶:B端产品经理必备的计算机专业技能精要
大数据·开发语言·人工智能·产品经理·编程语言·caie
科技树支点5 天前
无GC的Java创新设计思路:作用域引用式自动内存管理
java·python·go·web·编程语言·编译器
大熊猫侯佩8 天前
韦爵爷闯荡 Swift 6 江湖:单例秘籍新解(上)
swift·编程语言·apple
一支鱼9 天前
前端使用次数最多的工具封装
前端·typescript·编程语言
Jooolin9 天前
【C++】C++11都有什么新特性?
c++·ai编程·编程语言
秋难降11 天前
深入解析快速排序:原理、波动根源与优化之道
算法·排序算法·编程语言
咕白m62513 天前
Java 开发:用 Spire.PDF 高效压缩 PDF 文件
java·编程语言