Maison > Questions et réponses > le corps du texte
突然发现个问题,我们生活中的金融系统最多只有两位小数位,比如12.37,精确到分,但是当两位小数和非整数计算时也会得出三位小数啊,比如银行的日率,肯定会有计算得出三位小数或者更多小数位的,但是为什么我们只看得到两位小数的余额呢,多出的小数位不也是钱吗,被省略了吗,怎么省略的呢。感觉这个问题有点意思。
我的猜想:
实际上只要我们金融系统只是用两位小数,当产生超过两位小数时,后面的小数位都不要了,直接不要,而不是满五进一,如果进一,就造成多给用户钱了,哪怕是多给0.001元,这在整个系统中的损失也是巨大的,所以当出现两位以上的小数时,只能直接省去后面的小数位,哪怕是0.239也要省去0.009,这个0.009元的损失只能让用户承担。
比如银行的系统,支付宝,这些都是两位小数位的,我们一般余额字段都是使用decimal(10,2)
,保留两位小数位,我突然想到这个问题,好纠结,不知道是不是我想的那样。
比如支付宝使用积分,购物券抵扣同时下多个订单时,那个抵扣的钱好像就是根据订单金额的比例拆分到每个订单下面去了,这样就出现小数了,但是那个小数也是两位,我没仔细注意过,不知道多个订单的抵扣加起来是不是等于下单时抵扣的钱。
如果是我想的那样,那这样我感觉很多时候我们肯定损失了好多钱了?我原本想多保留几位小数就可以解决这个问题,可是感觉可能还会有无穷的小数,还是不太可能,难道就只能让用户损失钱吗,哪怕只是那么一点点。
希望大神指点一下,搞得我好迷惑,目前项目中正遇到了这类问题。
谢谢!
PHPz2017-04-11 09:43:32
当然不会是两位,在计算和存储都是6位及以上(有没有更多,不太清楚,但最少6位是肯定的)
只是算到最终给用户的 由于分之后无法兑现 所以就按照一定的算法计算最终结果。
PHP中文网2017-04-11 09:43:32
我觉得比较稳妥的方式的数据库存储的金额字段计量单位使用分,这样前台显示的时候先取整,再除100就是元了.
计算方式得分"给"和"收",以银行为主体的话,
"给":如果字段值是 200.11 那么算成元是2元零1.1厘..这个1.1厘可以舍去了,只给2元即可,就是说只取整数部分.
"收":相对可以自私一点.本着绝对不吃亏的设计原则,1厘也要算1分.那么就是字段值判断是否有小数点,有的话取整+1,没有的话直接取.如果本着四舍五入的话..各位大神就需要对有小数点的值进行判断和处理了.个人偏向绝对不吃亏原则,这个原则也应该是金融机构通用的原则.
重点时,用分做金额的计量单位,如果上亿的话,需要考虑下数据类型的Max,别超出范围了.