欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

程序中两个Double类型相加出现误差的解决办法

程序员文章站 2023-12-18 13:28:34
今天在自己做的系统中,发现了一个奇怪的现象:几个double类型的数据相加,到最后得出的金额比正确数值总是少了几毛钱。以为是程序里的计算方法有问题,可是排查了很多地方,始终...

今天在自己做的系统中,发现了一个奇怪的现象:几个double类型的数据相加,到最后得出的金额比正确数值总是少了几毛钱。以为是程序里的计算方法有问题,可是排查了很多地方,始终没有找到问题出在哪里。最后干脆把计算方法一句一句拆分,得到了最后最简单的一步,就是把两个具体的数值相加,但是最后的结果居然还是错误的。比如,现在已经到了最简单的一步:

复制代码 代码如下:

double n = 171.6;
double m = 28.17;
double k = n + m;

  按理说k的值应该是199.77,但其实得到的居然是199.76999999999998。

     我们的系统里有保留小数位数为4位,按理是可以四舍五入成199.77的。但是因为有做金额的合计,是几十甚至几百个数据的相加,由于每两个数相加的时候都可能产生上述误差,因此最后得到的结果已经有了近0.7的误差,就算再四舍五入也于事无补了。

     上网查了一下相关资料,觉得csdn论坛里的这个帖子的解释还是比较详细的:http://bbs.csdn.net/topics/300023952,大意是说由于运算的时候进行了进制的转换造成的(见8楼回复),所有的精度类型在几乎所有语言下都有这个问题。比较有效的解决办法是使用bigdecimal(见14楼回复),但是我个人认为那个bigdecimal的解决办法太麻烦了,至少对于我的系统来说是这样。还不如每加一次之后都进行一次字符串转换,保留有效的小数位数,比如,上述语句可以改写成:

复制代码 代码如下:

double n = 171.6;
double m = 28.17;
//double k = n + m;
string kn = (n + m).tostring("n4");    //保留4位小数
double k = convert.todouble(kn);

  也就是说,在string kn这一步,就已经把误差调整好了,得到的k值就是正确的了。这样每次相加都处理一下误差,无论要算多少个数据的合计也不用担心会出现误差过大的情况了。

    当然最好是把这种处理方法做成一个公用方法,专门用来处理两个数的相加。

上一篇:

下一篇: