66.6*100=6660?别再傻了!

347 阅读2分钟

前言

最近在做项目时遇到了金钱转换的问题,后端数据库保存数据的金额单位都是,后端骂骂咧咧地让前端自己处理,所以接口的接收的参数以及输出字段也都是。当前端页面显示和输入时金额时的单位必须是,这就要求在发送参数到后端时,需要先转换成;在页面回显时,再转换成

分和元互转函数封装

相信大家都会想当然的以为元转分不就乘以100嘛!分转元不就除以100嘛!然后就像如下封装函数:

// 元转分
yuanToFen(value) {
    return value * 100
}
// 分转元
fenToYuan(value) {
    return value / 100
}

如果只是这样,那你只对了一半,当元转分时,元可能会有浮点数,比如66.6元,当你使用66.6*100时,你会神奇的发现并不等于6660。其实涉及到浮点数计算是可能存在精度问题的,以下为几个栗子:

image.png

解决方案

big.js :用于处理任意精度的数值计算。它可以用于避免浮点数计算引起的精度问题,并提供了简单易用的接口。

BigNumber.js:是一个用于处理任意精度的十进制数的库。它提供了高精度的数值计算功能,可以避免浮点数计算引起的精度问题。

decimal.js:是另一个用于高精度数值计算的库。它支持任意精度的小数运算,并提供了一系列的数学函数和操作符。

mathjs:是一个全功能的数学库,其中包括了处理高精度数值的功能。它支持大整数、大浮点数和分数运算,提供了丰富的数学函数和表达式求值功能。

大家可根据需要自行选择使用哪个库,我这里选择的是big.js,会到以上的问题重新封装

import Big from 'big.js';
// 元转分
yuanToFen(value) {
    return new Big(value).times(new Big(100))
}
// 分转元
fenToYuan(value) 
    return new Big(value).div(new Big(100))
}

如果是整数的话分转元也可以不使用big.js计算,因为只是小数点向左移了两位。并不涉及浮点数计算问题。

总结

如果涉及到金额计算的话,最好引入第三方库来计算,防止精度丢失问题;当然还有一种解决方案,也是我觉得更好的解决方案,那就是涉及金额计算时,前端不做任何计算,全部由后端来计算。

阁下觉得呢?