想去互金拿高薪,先知金额如何存!

本文讨论了为何在存储货币数据时不应使用float和double类型,因为它们无法精确表示某些小数值,如0.7,导致计算误差。推荐使用BigDecimal进行精确存储和运算,虽然其运算复杂度较高,但能确保金额计算的准确性。总结了BigDecimal的使用方法以及其在处理货币计算时的优点和局限性。
摘要由CSDN通过智能技术生成

之前面试的时候被问到金额应该怎么存储,然后答的BigDecimal,然后因为真的没接触过,就没再多问什么,当初我也没多想就搁置了。然后昨天在看一个技术视频时候讲到金额存储,听完恍然大悟,今天来跟大家分享下。

之前就知道不能用float和和double存货币,但是不知道为什么不能存。那为什么不存呢?

1.为什么金额不能用float或double存呢?

首先,货币一般都会有小数,并且会有相应的计算。
先来看一个例子,猜猜如下代码打印的结果是什么?为什么?在这里插入图片描述





不就是true 嘛!

你确认吗?

真正的结果是false。
在这里插入图片描述
来看结果
在这里插入图片描述

这是为什么呢?

怎么price3变成了0.29999998呢?稍安勿躁,且听我缓缓道来。
我们都知道,计算机在存取数字的时候是通过二进制01存储的。那咱们先来把0.7转成二进制。
首先我们知道整数部分转成二进制是对2求余,然后倒叙就转成了二进制,直到余数为零为止,然后倒序排列就好了,我就不举例了,大家可以自己试下。那小数应该怎么转成二进制呢?

正好相反,乘以2,首先把整数位置为0,然后对它进行乘2处理,然后取整数位的值,然后再把整数位置为0,再对它乘以2,再取整数位,直到小数位全部为0为止。
计算过程

0.7 *2 =1.4 得 1
0.4 *2 =0.8 得 0
0.8 *2 =1.6 得 1
0.6 *2 =1.2 得 1
0.2 *2 =0.4 得 0



发现没?第五行跟第二行一样了,产生了循环。所以0.7转换为二级制是0.101100110…它是无穷的。

因为计算机存储是有限位数,所以计算机并不能准确的表示0.7这个数字。

本来我也以为只有像π和三分之一那种无穷值不能存储的,没想到这个也不能存。其实也没有错,为啥呢?

因为0.7的二进制是无穷的。对于无穷的值,计算机也无能为力。
在这里插入图片描述

既然这种无穷数,float不能精确的存,那double也一样,只不过五十步笑百步罢了。只不过精度高低罢了。

2.那该怎么解决呢?

解决方案就是使用BigDecimal存储和运算,它可以精确的运算。
因为它存储时把小数转换(乘以10的次方)成整数存储。这样就不会有小数转换二进制的很有可能出现无穷值的破事了。

具体怎么操作呢?

首先获取货币的小数的总位数,然后直接乘以10的N次方转换成对应的长整型,再存储。

例如 存储17.1354元,直接乘以10000,存为171354,到运算的时候,直接用整型计算,需要显示的时候,再等比例缩小为原始精度即可。
在这里插入图片描述
来看下计算结果

在这里插入图片描述

那它有没有缺点呢?当然有了
1.首先复杂的数字计算起来不太方便;
因为bigDecmal计算的时候必须使用bigDecimal类内部的运算方法。所以复杂的运算还是不太方便的。
2.在调用bigDecimal的divide方法(即除法)时,要规定小数的保留位数。否则在除不尽的时候,会报错。

总结
今天总结下小数存储和计算的方案,当存金额的数据时,还是要多多考虑的。祝各位在未来的日子里,薪资翻倍,不掉头发。

❤️ 看完两件事
如果你觉得这篇内容对你有帮助,我想邀请你帮我个小忙:

  1. 关注我,并且点赞,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)。
  2. 也看看我的其它文章。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值