最近遇到一个bug ,在java里面计算两个数字相减,633011.20-31296.30

得到的结果居然是601714.8999999999,丢失精度了,原来这是Java浮点运算的一个bug。

解决方法:网上找到了一些解决办法,就是重新写了一些浮点运算的函数。
下面就把这些方法摘录下来,以供遇到同样问题的朋友参考:

简易计算器点击下载

js中多个数字运算后值不对(失真)处理方法

调用方法:

public static void main(String[] args) throws Exception{
System.out.println("加法未处理:0.05+0.01="+(0.05+0.01));
System.out.println("加法已处理:0.05+0.01="+add(0.05,0.01));
System.out.println("减法未处理:1.0-0.42="+(1.0-0.42));
System.out.println("减法已处理:1.0-0.42="+sub(1.0,0.42));
System.out.println("减法未处理:633011.20-31296.30="+(633011.20-31296.30));
System.out.println("减法已处理:633011.20-31296.30="+sub(633011.20,31296.30));
System.out.println("乘法未处理:4.015*10="+(4.015*100));
System.out.println("乘法已处理:4.015*10="+mul(4.015,100));
System.out.println("除法未处理:123.3/100="+(123.3/100));
System.out.println("除法已处理:123.3/100="+division(123.3,100));
}

控制台输出效果:

加法未处理:0.05+0.01=0.060000000000000005
加法已处理:0.05+0.01=0.06
减法未处理:1.0-0.42=0.5800000000000001
减法已处理:1.0-0.42=0.58
减法未处理:633011.20-31296.30=601714.8999999999
减法已处理:633011.20-31296.30=601714.9
乘法未处理:4.015*10=401.49999999999994
乘法已处理:4.015*10=401.5
除法未处理:123.3/100=1.2329999999999999
除法已处理:123.3/100=1.23

java程序代码

1.加法运算

    /**
* 计算两个值的加法运算
* @param arg1
* @param arg2
* @return
* @throws Exception
*/
public static double add(double arg1,double arg2) throws Exception{
String arg11 = arg1+"";
String arg22 = arg2+"";
int r1 = 0;
int r2 = 0;
int m = 0;
try{
r1=arg11.split("\\.")[1].length();
}catch(Exception e){
r1=0;
}
try{
r2=arg22.split("\\.")[1].length();
}catch(Exception e){
r2=0;
}
m=(int) Math.pow(10,Math.max(r1,r2)); return (arg1 * m + arg2 * m)/m;
}

2.减法运算

    /**
* 计算两个值的减法运算
* @param arg1
* @param arg2
* @return
* @throws Exception
*/
public static double sub(double arg1,double arg2) throws Exception{
String arg11 = arg1+"";
String arg22 = arg2+"";
int r1 = 0;
int r2 = 0;
int m = 0;
int n = 0;
try{
r1=arg11.split("\\.")[1].length();
}catch(Exception e){
r1=0;
}
try{
r2=arg22.split("\\.")[1].length();
}catch(Exception e){
r2=0;
} m = (int)Math.pow(10, Math.max(r1, r2));
//last modify by deeka
//动态控制精度长度
n = (r1 >= r2) ? r1 : r2;
double result = ((arg1 * m - arg2 * m) / m); //BigDecimal.ROUND_HALF_UP表示四舍五入,BigDecimal.ROUND_HALF_DOWN也是五舍六入,BigDecimal.ROUND_UP表示进位处理(就是直接加1),BigDecimal.ROUND_DOWN表示直接去掉尾数。
BigDecimal b = new BigDecimal(result);
result = b.setScale(n, BigDecimal.ROUND_HALF_UP).doubleValue();
return result;
}

3.乘法运算

    /**
* 计算两个值的乘法运算
* @param arg1
* @param arg2
* @return
* @throws Exception
*/
public static double mul(double arg1,double arg2) throws Exception{
String arg11 = arg1+"";
String arg22 = arg2+"";
int m = 0;
try{
m+=arg11.split("\\.")[1].length();
}catch(Exception e){
System.out.println("计算出错");
}
try{
m+=arg22.split("\\.")[1].length();
}catch(Exception e){
System.out.println("计算出错");
}
return Integer.parseInt(arg11.replace(".",""))*Integer.parseInt(arg22.replace(".",""))/Math.pow(10,m);
}

4.除法运算

    /**
* 计算两个值的除法运算
* @param arg1
* @param arg2
* @return
* @throws Exception
*/
public static double division(double arg1,double arg2) throws Exception{
String arg11 = arg1+"";
String arg22 = arg2+"";
int t1 = 0;
int t2 = 0;
int r1 = 0;
int r2 = 0;
try{
t1=arg11.split("\\.")[1].length();
}catch(Exception e){
System.out.println("计算出错");
}
try{
t2=arg22.split("\\.")[1].length();
}catch(Exception e){
System.out.println("计算出错");
}
r1=Integer.parseInt(arg11.replace(".",""));
r2=Integer.parseInt(arg22.replace(".",""));
double result = ((float)r1/r2)*(Math.pow(10,t2-t1));
//BigDecimal.ROUND_HALF_UP表示四舍五入,BigDecimal.ROUND_HALF_DOWN也是五舍六入,BigDecimal.ROUND_UP表示进位处理(就是直接加1),BigDecimal.ROUND_DOWN表示直接去掉尾数。
BigDecimal b = new BigDecimal(result);
result = b.setScale(t1 + t2, BigDecimal.ROUND_HALF_UP).doubleValue();
return result;
}

java中多个数字运算后值不对(失真)处理方法的更多相关文章

  1. js中多个数字运算后值不对(失真)处理方法

    最近遇到一个bug ,在js里面计算两个数字相减,633011.20-31296.30 得到的结果居然是601714.89,领导不乐意了说怎么少了0.01,我一听,噶卵达,来达鬼,不可能啊,我Goog ...

  2. Java中url传递中文参数取值乱码的解决方法

    java中URL参数中有中文值,传到服务端,在用request.getParameter()方法,得到的常常会是乱码,这将涉及到字符解码操作. 方法一: http://xxx.do?ptname=’我 ...

  3. js中Number数字数值运算后值不对

    问题: 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两 ...

  4. Java中的Bigdecimal类型运算

    Java中的Bigdecimal类型运算 双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行运算和处理.Java在java.math包中提 供的API类BigD ...

  5. java中int,float,long,double取值范围,内存泄露

    java中int,float,long,double取值范围是多少? 写道 public class TestOutOfBound { public static void main(String[] ...

  6. Java 中 List 向前和向后遍历

    Java 中 List 向前和向后遍历 import java.util.*; public class TestCollectionIterator { public static void mai ...

  7. 转:Java中子类是否可以继承父类的static变量和方法而呈现多态特性

    原文地址:Java中子类是否可以继承父类的static变量和方法而呈现多态特性 静态方法 通常,在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法,关于static方法,声明 ...

  8. java中多线程执行时,为何调用的是start()方法而不是run()方法

    Thead类中start()方法和run()方法的区别 1,start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程,通过Thead类中start()方法来启动的线程处于就绪状 ...

  9. 初识Java(Java数字处理类-大数字运算)

    一.大数字运算 在 Java 中提供了大数字的操作类,即 java.math.BigInteger 类与  java.math.BigDecimal 类.这两个类用于高精度计算,体重 BigInteg ...

随机推荐

  1. 去掉JAVA部分依赖的事例

    一.现象 最近做JAVA项目,需要依赖一个外部的JAR包,但是依赖之后,发现eclipse一直workspace,估计是包重复加载的问题 二.问题 使用查看包依赖的命令:mvn dependency: ...

  2. SQL Server临时表

    []SQL Server临时表]()https://docs.microsoft.com/zh-cn/sql/relational-databases/tables/temporal-tables)

  3. OpenCV实现任意大小图片的合并(转)

    OpenCV实现图像合并主要有两种方法 方法一:使用Mat.push_back方法将列数相同的图像加到最后一行 方法二: 主要思路是将图像拷贝到待合并图像的感兴趣区域 (1)新建一个要合并的图像(容器 ...

  4. Cocos2d 编译js为jsc bytecode文件

    使用: cocos jscompile -s XXX(目录名,会递归) -d (输出的目录)   但编译后的jsc比原来的js更大了     如果只是为了代码的保密性,也许只需要用yuicompres ...

  5. MySQL参数化查询的IN 和 LIKE

    https://stackoverflow.com/questions/650455/c-sharp-parameterized-query-mysql-with-in-clausehttps://s ...

  6. .NET/C#中对自定义对象集合进行自定义排序的方法

    一个集合可否排序,要看系统知不知道排序的规则,像内建的系统类型,int ,string,short,decimal这些,系统知道怎么排序,而如果一个集合里面放置的是自定义类型,比如自己定义了一个Car ...

  7. Echarts学习记录——如何给x轴文字标签添加事件

    Echarts学习记录——如何给x轴文字标签添加事件 关键属性 axisLabel下属性clickable:true 并给图表添加单击事件 根据返回值判断点击的是哪里 感觉自己的方法有点变扭,有更好办 ...

  8. 微软Xbox One无线手柄控制机器人

    ROS中的joy包提供了游戏手柄的驱动,并且包含joy_node节点,这一节点可以发布包含手柄按钮和轴信息的Joy消息.在终端中输入下面命令,安装joy包: $ sudo apt-get instal ...

  9. foxmail怎么设置个性签名

    foxmail是我们日常使用的邮件客户端之一,相信很多的朋友都在使用.那么,我们在发邮件的时候,很多朋友都会使用一个个性签名,那么对于foxmail的邮件签名怎么来设置呢?今天笔者就来给大家分享一下, ...

  10. 跟我学Shiro---无状态 Web 应用集成

    无状态 Web 应用集成 在一些环境中,可能需要把 Web 应用做成无状态的,即服务器端无状态,就是说服务器端不会存储像会话这种东西,而是每次请求时带上相应的用户名进行登录.如一些 REST 风格的 ...