漫谈:浮点数为什么很麻烦 金额究竟应该如何存储

浮点数是个很麻烦的东西,浮点数是不精确的。

不精确的原因不是因为精度不足,而是因为十进制和二进制在小数部分的转换可能是无法精确对应的。

二进制的整数部分,跟十进制相比,不过是长了一些。

二进制的小数部分,第一位是0.5,第二位是0.25,第三位是0.125,依此类推。那么十进制0.1的二进制什么样?

第一位不够,0

第二位不够,0

第三位还是不够,0

第四位是0.0625,够,1,剩余0.0375

第五位是0.03175,够,1,剩余0.00575

再继续......可以想象,后面遇到一个凑巧可以使剩余为0的不会很容易。

0.1的二进制是0.0001100110011001100110011001100110011001100110011001101(我不知道后面还有没有)。

一种进制下简单的数,在另一种数制下可能是无限的。

比如十进制三分之一,是个无限循环小数0.3333333......,而对于三进制,就是0.1啊,多简单。(三进制计算机并非没有人尝试过)

所以说,这不是精度问题,精度再高也不能存储无限多的数字。

所有C语言教材在讲到浮点数的时候应该都会讲到不可以对浮点数进行==比较,只能用"x-a<0.000001 || a-x<0.000001"之类的方法来比较,差值的绝对值小于某个数就算相等。

学习数值计算的时候,第一课就是浮点数的精度问题,不仅仅是不精确,而且,浮点数的运算顺序也严重会影响结果,书上的建议是,避免对数量级差别很大的数字进行运算。当然,数值运算是一个专门的领域,解方程的,逃不开浮点数。

对于大部分程序员而言,现实中很少用到浮点数。遇到金额问题怎么办?其实与金额有关的计算都有最小单位要求,不到最小单位的按规定舍去或进位,程序都是用整数来存储数据的。

比如有些系统业务要求就是精确到分,所以所有金额在内部就是直接乘以100,按照分来存储的。

数据库和高级语言基本都支持Decimal类型,专门用于存储金融类型,其实就是保持了十进制,避免了转换到二进制造成的误差。但是呢,没有CPU支持啊!所以一定会很慢。

(这里是结束)

相关推荐
眠りたいです11 小时前
基于脚手架微服务的视频点播系统-数据管理与网络通信部分的预备工作
c++·qt·ui·微服务·云原生·架构·媒体
烦躁的大鼻嘎11 小时前
【Linux】深入Linux多线程架构与高性能编程
linux·运维·服务器·开发语言·c++·ubuntu
野生的编程萌新11 小时前
【C++深学日志】C++编程利器:缺省参数、函数重载、引用详解
c语言·开发语言·c++
愚润求学11 小时前
【贪心算法】day10
c++·算法·leetcode·贪心算法
智者知已应修善业12 小时前
【矩阵找最大小所在位置】2022-11-13
c语言·c++·经验分享·笔记·算法·矩阵
小柯J桑_12 小时前
C++之特殊类设计
java·开发语言·c++
屁股割了还要学12 小时前
【数据结构入门】排序算法(4)归并排序
c语言·数据结构·学习·算法·排序算法
SccTsAxR12 小时前
[C语言]常见排序算法①
c语言·开发语言·经验分享·笔记·其他·排序算法
笑口常开xpr12 小时前
Linux 库开发入门:静态库与动态库的 2 种构建方式 + 5 个编译差异 + 3 个加载技巧,新手速看
linux·c语言·动态库·静态库
bikong712 小时前
Qt/C++,windows多进程demo
c++·windows·qt