`
zhanglu0223
  • 浏览: 21503 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

Java中的数字基本运算和精度问题

 
阅读更多

一.精度

举例:double result = 1.0 - 0.9;

这个结果不用说了吧,都知道了,0.09999999999999998

float和double类型主要是为了科学计算和工程计算而设计的。他们执行二进制浮点运算,这是为了在广泛的数字范围上提供较为精确的快速近似计算而精心设计的。然而,它们并没有提供完全精确的结果,所以我们不应该用于精确计算的场合。float和double类型尤其不适合用于货币运算,因为要让一个float或double精确的表示0.1或者10的任何其他负数次方值是不可能的(其实道理很简单,十进制系统中能不能准确表示出1/3呢?同样二进制系统也无法准确表示1/10)。

浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用float和double作精确运算的时候要特别小心。

Java代码收藏代码
  1. doubleresult=1.0-0.9;//坏代码

二.解决精度丢失有几种比较常用的方法

1.用NumberFormat类来格式化计算结果,按照自己想要的结果进行格式化,缺点就是要手动去格式化,舍入方式不同结果不一定精确。

Java代码收藏代码
  1. //好代码
  2. doubleresult=1.0-0.9;
  3. NumberFormatnf=NumberFormat.getInstance();//根据自己的需求格式化
  4. StringresultStr=nf.format(result);

2.如果不介意自己记录十进制的小数点,而且数值不大,那么可以使用long,int等基本类型,具体用int还是long要看涉及的数值范围大小,缺点是要自己处理十进制小数点,最明显的做法就是处理货币使用分来计算,而不用元(只涉及加减)。

Java代码收藏代码
  1. //好代码
  2. intresultInt=10-9;
  3. doubleresult=(double)resultInt/100;//最终时候自己控制小数点

3.使用BigDecimal来代替double,它能让你完全控制精度,结果会非常精确,加减乘除写起来也很方便,不过他有两个缺点:1,不是基本类型,与基本类型相比,操作起来不方便;2.速度没有基本类型快,算是用速度换精度。相比第2个缺点并不要紧,但是第一个缺点会让你写起代码很不舒服。

Java代码收藏代码
  1. //好代码
  2. Stringresult=newBigDecimal("1").subtract(newBigDecimal("0.9")).toString();

个人比较喜欢这个,而且BigDecimal还支持常用的格式化方法,如

BigDecimal num = new BigDecimal("384400000");

String str = new DecimalFormat("地球和月球的距离:#,##,###,###米").format(num);

结果:地球和月球的距离:384,400,000米

Java代码收藏代码
  1. //任意使用double或float进行数学运算,而忽略精度。//坏代码
  2. //数学计算考虑数到了精度问题。//好代码

三.浮点类型的比较

由于精度问题,double/float比较相等也不能直接使用==,但是比较大小可以用<、>号

Java代码收藏代码
  1. doubled1=0.1,d2=0.1;
  2. if(d1==d2){}//坏代码
  3. if(Double.compare(d1,d2)==0){}//好代码
  4. if(Double.doubleToLongBits(d1)==Double.doubleToLongBits(d2)){}//好代码
  5. if(Double.valueOf(d1).equals(d2)){}//好代码,1.5以上

四.合理使用第三方工具类

apache的commons-lang工具包中个math包,提供了常用的计算方法,数字处理方法,如果项目中涉及到的计算比较多,可以考虑使用commons-math包,这个包过于专业化,估计咱们用到的地方不多。

apache的commons-lang的math包,主要有4大类功能

1.处理分数的Fraction类,分数表示数字,更为精确。

Java代码收藏代码
  1. Fractionfraction=Fraction.getFraction(10,3);//三分之十
  2. System.out.println(fraction);//10/3
  3. System.out.println(fraction.floatValue());//3.3333333
  4. System.out.println(fraction.doubleValue());//3.3333333333333335
  5. System.out.println(fraction.toProperString());//三又三分之一
  6. System.out.println(fraction.reduce());//约分,如2/4约分后1/2

2.处理数值的NumberUtils类;这个比较简单,看看api就可以。封装了一些常用数字操作方法,如数字转换、比较,获取一个数字数组中最大值,最小值等。

3.处理数值范围的Range、NumberRange、IntRange、LongRange、FloatRange、DoubleRange类;

Java代码收藏代码
  1. //拿int举例,其他类似
  2. IntRangeintRange=newIntRange(100,200);//创建一个范围
  3. intRange.containsDouble(111.1);//是否包含指定数字
  4. int[]range=intRange.toArray();//获取范围内的int
  5. intRange.getMaximumDouble();//获取最大值,转换成double
  6. intRange.getMinimumDouble();//获取最小值,转换成double

4.处理随机数的JVMRandom和RandomUtils类。这个也比较简单,看看api就可以,获取随机数时比较方便而已。

commons-math工具包是apache上一个轻量级自容器的数学和统计计算方法包,包含大多数常用的数值算法,这个进行专业数学处理时会非常方便。

如:计算方法,方差和一组数的概率统计问题;

一套拟合曲线的数据点应用线性回归问题;

插值问题(可能包括线性、样条等插值);

用来进行参数拟合的最小二乘方法;

求解方程组值问题(例如,求方程组的根);

解决系统的线性方程组;

求解常微分方程;

求最小值问题的方法;

利用Commons Math包产生指定要求的随机数;

生成随机抽样,数据集;

进行统计测试;

繁杂的数学函数,如组二项式系数、特殊函数(如gamma, beta functions);

个人认为这个包过于专业,如果用到了,再查询不迟,知道这个包能解决问题就行。

当然,这个包很专业,但是不代表只能解决专业数学问题,处理简单的计算也是很方便的。

总结:普通的计算最好使用BigDecimal类,这个类可以非常精确的计算出结果,而且你可以完全控制精度,不用额外其他操作,而且与基本类型转换都非常方便。

分享到:
评论

相关推荐

    bignumber.min.js下载

    众所周知,数字运算的精度问题是一个让人很旦疼的问题,而java中有BigDecimal类对数字精度问题进行处理,经过一番查询,发现前段有一个宝藏精度处理类bignumber。亲测好用。 众所周知,数字运算的精度问题是一个让人...

    解决JavaScript数字精度丢失问题的方法

    JS 数字精度丢失的一些典型问题 JS 数字精度丢失的原因 解决方案(一个对象+一个函数) 一、JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加 0.1 + 0.2 != 0.3 // true 这真不是 Firebug 的问题,可以用...

    Java的数学运算处理类讲解代码(BigDecimal、Math、Random、DecimalFormat类全部操作方法API)

    这个源码资源是一个讲解数学计算处理类的示例项目,旨在帮助开发者理解和使用Java中的数学计算相关类库。该项目包含详细的代码示例和注释,涵盖了以下几个主要的数学计算处理类:BigDecimal、Math、Random和...

    Java Number & Math 类.pdf

    Java Number类提供了以下基本的数字操作:转换,比较,算术运算,取整,取余,取最大值和最小值,取绝对值,取幂,取对数,取根号,取随机数,取符号,取精度,取舍入值等。 三、什么是包装类? 在实际开发过程中,...

    人工智能四则运算手写体识别训练模型

    能够区分0-9的数字,以及+,-,*,/,()运算符,支持括号运算,识别精度达到90%以上,需要的请自取

    Java的数字精确计算问题-BigDecimal

    java的数字运算,偶尔会出现精度的问题,以下阐述的 java的BigDecimal类的使用.  例如:  System.out.println(0.9+0.3); 结果1.2  System.out.println(1.9+0.3); 结果2.1999999999999997  System.out....

    Java的8大基本数据类型.pdf

    Java的 的8⼤基本数据类型 ⼤基本数据类型 Java8⼤基本数据类型 ⼤基本数据类型 byte(字节型)、short(短整型)、int (整型) 、long(长整型) float(单精度浮点型)、double(双精度浮点型)、boolean(布尔型)、...

    ArithmeticUtils用于高精确处理常用的数学运算工具类

    ArithmeticUtils用于高精确处理常用的数学运算工具类 提供精确的加法运算 提供精确的减法运算 ...当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入 提供精确的小数位四舍五入处理 取余数 比较大小

    java编写的计算器,能实现加减乘除

    //使用内存中存储的数字 int memoryi; double vard, answerd; //用来保存double型数据的中间值(vard)和最后结果(answerd) short key = -1, prekey = -1; //key用来保存当前进行何种运算,prekey用来保存...

    详谈javascript精度问题与调整

    一个经典的问题: 0.1+0.2==0.3 答案是:false 因为:0.1+0.2=0.30000000000000004 ...1.32位的浮点数(单精度),最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。 浮点数的表现形式: x=(-1)^S*

    基于Java的Android应用程序开发-24点游戏源码+详细项目说明.zip

    使用一个列表存储目前的全部数字,每次从列表中选出2个数字,再选择一种运算操作,用计算得到的结果取代选出的2个数字,这样列表中的数字就减少了1个。重复上述步骤,直到列表中只剩下1个数字,这个数字就是一种可能...

    java中BigDecimal进行加减乘除的基本用法

    大家应该对于不需要任何准确计算精度的数字可以直接使用float或double运算,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数的操作。下面这篇文章就给大家介绍介绍关于...

    JavaDemical:Java 数字API

    否则,通过向该操作提供适当的MathContext对象,可以对已选择的精度和舍入模式执行计算。 在商业计算中要用BigDecimal。BigDecimal所创建的是对象, 我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学...

    基于Java(Android)实现多机系统【100011035】

    本系统基于设计文档开发,利用 Java 作为主要编程代码。我所用的实验环境是 Mac Mini ...如没有特殊声明,此系统中所使用的各类参数,除高精度加法所使用的数字是 String 类型外,其他参数均为 int 或 Integer 类型。

    整理后java开发全套达内学习笔记(含练习)

    进行高精度运算可以用java.math包中BigDecimal类中的方法。 自动类型提升又称作隐式类型转换。 强制类型转换:int ti; (byte) ti ; 强制转换,丢弃高位 宣告变量名称的同时,加上“final”关键词来限定,这个...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    本书是第II卷,以开发人员在项目开发中经常遇到的问题和必须掌握的技术为中心,介绍了应用Java进行桌面程序开发各个方面的知识和技巧,主要包括Java语法与面向对象技术、Java高级应用、窗体与控件应用、文件操作...

    java_资金运算工具类_提供精确的加减乘除法等运算

    一些工具类代码块的集合: 提供精确的加法运算 ...当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入 提供精确的小数位四舍五入处理 取余数 取余数 BigDecimal 比较大小 获取自己想要的数据格式

    java计算器程序.doc

    //需要解决的问题,数学的运算都有正负号的出现,在点击等号的时候就会有冲突,应该怎样解决,经验:双精度浮点型数据类型是会像后减一位。0.7会显示成0.69999999 public class app74 { static int i=0; static ...

Global site tag (gtag.js) - Google Analytics