mysql精度丢失无法入库_两种精度丢失问题

这篇博客探讨了在JavaScript中进行小数运算时出现的精度问题,以及如何通过自定义函数解决加减法中保留两位小数的需求。同时,文章提到了在MySQL中类似的问题,特别是字符串与数字相加时可能出现的精度丢失现象。解决方案是利用`TRUNCATE`函数来确保结果保留两位小数。博客强调了在处理金钱计算时精确性的关键性,并提供了跨数据库平台的兼容性考虑。
摘要由CSDN通过智能技术生成

最近在工作中频繁的遇到精度问题

1、在js中,当两个带小数点的数值进行加减运算时,在某些特殊情况下如小数点末尾为9或相加为9等情况,则存在精度问题,结果为两位小数点的数据计算出来的结果为很长一串。

解决办法:由于业务涉及到钱,所以不能使用四舍五入,只能采取直接截取或别的,目的是保留两位小数。

在尝试多种方法后 如使用toFix方法,转换成decimal等后均不能解决问题,后来自己实现了两个方法,一个相加一个相减。方法的核心是根据小数位数扩大相应倍数进行计算。

方法如下:

/**

* 加法运算,避免数据相加小数点后产生多位数和计算精度损失。

*

* @param num1加数1 | num2加数2

*/

function numAdd(num1, num2) {

var baseNum, baseNum1, baseNum2;

try {

baseNum1 = num1.toString().split(".")[1].length;

} catch (e) {

baseNum1 = 0;

}

try {

baseNum2 = num2.toString().split(".")[1].length;

} catch (e) {

baseNum2 = 0;

}

baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));

return (num1 * baseNum + num2 * baseNum) / baseNum;

};

/**

* 加法运算,避免数据相减小数点后产生多位数和计算精度损失。

*

* @param num1被减数 | num2减数

*/

function numSub(num1, num2) {

var baseNum, baseNum1, baseNum2;

var precision;// 精度

try {

baseNum1 = num1.toString().split(".")[1].length;

} catch (e) {

baseNum1 = 0;

}

try {

baseNum2 = num2.toString().split(".")[1].length;

} catch (e) {

baseNum2 = 0;

}

baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));

precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2;

return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);

};

2、今日在mysql中也遇到类似的问题。由于也涉及到金钱,所以不能马虎。

select 20.43+'1.99',20.43+1.99得到的结果不一样。前者是数字与字符串数字相加,后者是纯数字类型相加。但是前者产生了精度问题。

得到的结果如下

98c9cd6ddc5d7e8972e5b5bfa34bb0e7.png

多次试验之后发现,并不是所有的数字与字符串相加都会有精度问题,似乎当有一个小数的末尾为9或者小数点后一位相加等于9时会出现此种问题。猜想估计是mysql中字符串转数字的算法问题导致的。

经过db2数据库的校验,此种计算在db2中不存在问题。

解决办法:结果保留两位小数。使用truncate计算之后截取。

select 20.43+'1.99',truncate('1.99'+20.43,2),188.48+'3000.01',truncate(188.48+'3000.01',2)

cast函数和convert函数不满足要求。

由于多次遇到,故作记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值