java中多个数字运算后值不对(失真)处理方法
最近遇到一个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中多个数字运算后值不对(失真)处理方法的更多相关文章
- js中多个数字运算后值不对(失真)处理方法
最近遇到一个bug ,在js里面计算两个数字相减,633011.20-31296.30 得到的结果居然是601714.89,领导不乐意了说怎么少了0.01,我一听,噶卵达,来达鬼,不可能啊,我Goog ...
- Java中url传递中文参数取值乱码的解决方法
java中URL参数中有中文值,传到服务端,在用request.getParameter()方法,得到的常常会是乱码,这将涉及到字符解码操作. 方法一: http://xxx.do?ptname=’我 ...
- js中Number数字数值运算后值不对
问题: 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两 ...
- Java中的Bigdecimal类型运算
Java中的Bigdecimal类型运算 双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更小的数进行运算和处理.Java在java.math包中提 供的API类BigD ...
- java中int,float,long,double取值范围,内存泄露
java中int,float,long,double取值范围是多少? 写道 public class TestOutOfBound { public static void main(String[] ...
- Java 中 List 向前和向后遍历
Java 中 List 向前和向后遍历 import java.util.*; public class TestCollectionIterator { public static void mai ...
- 转:Java中子类是否可以继承父类的static变量和方法而呈现多态特性
原文地址:Java中子类是否可以继承父类的static变量和方法而呈现多态特性 静态方法 通常,在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法,关于static方法,声明 ...
- java中多线程执行时,为何调用的是start()方法而不是run()方法
Thead类中start()方法和run()方法的区别 1,start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程,通过Thead类中start()方法来启动的线程处于就绪状 ...
- 初识Java(Java数字处理类-大数字运算)
一.大数字运算 在 Java 中提供了大数字的操作类,即 java.math.BigInteger 类与 java.math.BigDecimal 类.这两个类用于高精度计算,体重 BigInteg ...
随机推荐
- Java通过ScriptEngine 执行js脚本案例
public static void main(String[] args) throws ScriptException, FileNotFoundException, NoSuchMethodEx ...
- 什么是Session分布式共享
在了解session分布式共享之前先来了解Session.Redis和Nginx的相关知识. 一.Session相关知识 1.Session 介绍 Session在网络应用中,称为“会话控制”. 每个 ...
- selenium安装使用
pip isntall selenium chromedriver download copy到chrome的安装目录, 并将这个路径加到环境变量的path中 chromedriver与chrome各 ...
- ORA-01940: 无法删除当前连接的用户
删除用户报错 SQL> drop user ODI_SRC CASCADE; drop user ODI_SRC CASCADE * 第 1 行出现错误: ORA: 无法删除当前连接的用户 查看 ...
- 用RotateDrawable实现网易云音乐唱片机效果
imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="唱片机" title=""> ...
- X-Forwarded-For 会少记录一次代理服务器的IP
X-Forwarded-For是一个Http请求头中的项目. 当一个请求经过代理时,X-Forwarded-For将被记录下来,规则如下: 假设用户U,通过代理服务器A,请求到服务器S, 那么X-Fo ...
- centos6.5官方dvd做本地yum
问题描述: 一切都搞定了,就是yum makecache 出现文件404,再目录看了也不对没后缀...(这不扯淡吗,rhel的dvd是可以直接使用的,难道企业版与社区版的区别??) 日志记录 [roo ...
- window.parent 与 Window.top
window.parent 返回当前窗口的父窗口对象. 如果一个窗口没有父窗口,则它的 parent 属性为自身的引用. 如果当前窗口是一个 <iframe>, <object> ...
- Oracle 9i 10g 11g 区别的转载
下面看看9i.10g.11g版本的区别 Oracle 10g比9i多的新特性? 1. 10g支持网格计算,即多台结点服务器利用高速网络组成一个虚拟的高性能服务器,负载在整个 网格中衡(L ...
- 详解iOS多图下载的缓存机制
1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cell里显示一张图片,而且这些图片都需要从网上下载. 2. 容易遇到的问题 如果不知道或不使用异步操作和缓存机制,那么写出 ...