最近遇到一个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通过ScriptEngine 执行js脚本案例

    public static void main(String[] args) throws ScriptException, FileNotFoundException, NoSuchMethodEx ...

  2. 什么是Session分布式共享

    在了解session分布式共享之前先来了解Session.Redis和Nginx的相关知识. 一.Session相关知识 1.Session 介绍 Session在网络应用中,称为“会话控制”. 每个 ...

  3. selenium安装使用

    pip isntall selenium chromedriver download copy到chrome的安装目录, 并将这个路径加到环境变量的path中 chromedriver与chrome各 ...

  4. ORA-01940: 无法删除当前连接的用户

    删除用户报错 SQL> drop user ODI_SRC CASCADE; drop user ODI_SRC CASCADE * 第 1 行出现错误: ORA: 无法删除当前连接的用户 查看 ...

  5. 用RotateDrawable实现网易云音乐唱片机效果

    imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="唱片机" title=""> ...

  6. X-Forwarded-For 会少记录一次代理服务器的IP

    X-Forwarded-For是一个Http请求头中的项目. 当一个请求经过代理时,X-Forwarded-For将被记录下来,规则如下: 假设用户U,通过代理服务器A,请求到服务器S, 那么X-Fo ...

  7. centos6.5官方dvd做本地yum

    问题描述: 一切都搞定了,就是yum makecache 出现文件404,再目录看了也不对没后缀...(这不扯淡吗,rhel的dvd是可以直接使用的,难道企业版与社区版的区别??) 日志记录 [roo ...

  8. window.parent 与 Window.top

    window.parent 返回当前窗口的父窗口对象. 如果一个窗口没有父窗口,则它的 parent 属性为自身的引用. 如果当前窗口是一个 <iframe>, <object> ...

  9. Oracle 9i 10g 11g 区别的转载

    下面看看9i.10g.11g版本的区别 Oracle 10g比9i多的新特性?        1. 10g支持网格计算,即多台结点服务器利用高速网络组成一个虚拟的高性能服务器,负载在整个 网格中衡(L ...

  10. 详解iOS多图下载的缓存机制

    1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cell里显示一张图片,而且这些图片都需要从网上下载. 2. 容易遇到的问题 如果不知道或不使用异步操作和缓存机制,那么写出 ...