`
雪飘寒
  • 浏览: 30512 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

    博客分类:
阅读更多

 

. 精度

 

举例:double result = 1.0 - 0.9;

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

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

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

 

 

double result = 1.0 - 0.9;//坏代码
 

 

 

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

 

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

 

// 好代码
double result = 1.0 - 0.9;
NumberFormat nf = NumberFormat.getInstance();// 根据自己的需求格式化
String resultStr = nf.format(result);
 

 

 

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

 

// 好代码
int resultInt = 10 - 9;
double result = (double) resultInt / 100;//最终时候自己控制小数点
 

 

 

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

 

// 好代码
String result = new BigDecimal("1").subtract(new BigDecimal("0.9")) .toString();
 

 

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

BigDecimal num = new BigDecimal("384400000");

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

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

 

 

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

 

 

. 浮点类型的比较

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

 

 

double d1 = 0.1, d2 = 0.1;
if (d1 == d2) {}// 坏代码
if (Double.compare(d1, d2) == 0) {}// 好代码
if (Double.doubleToLongBits(d1) == Double.doubleToLongBits(d2)) {}// 好代码
if (Double.valueOf(d1).equals(d2)) {}// 好代码,1.5以上
 

 

 

. 合理使用第三方工具类

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

apachecommons-langmath包,主要有4大类功能

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

 

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

 

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

3. 处理数值范围的RangeNumberRangeIntRangeLongRangeFloatRangeDoubleRange类;

 

// 拿int举例,其他类似
IntRange intRange = new IntRange(100, 200);// 创建一个范围
intRange.containsDouble(111.1);// 是否包含指定数字
int[] range = intRange.toArray();// 获取范围内的int
intRange.getMaximumDouble();// 获取最大值,转换成double
intRange.getMinimumDouble();// 获取最小值,转换成double
 

 

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

 

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

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

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

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

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

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

解决系统的线性方程组;

求解常微分方程;

求最小值问题的方法;

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

生成随机抽样,数据集;

进行统计测试;

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

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

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

 

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

 

 

分享到:
评论

相关推荐

    Java编写的大数运算

    `BigDecimal`提供了构造函数来创建任意精度的数字,以及多种方法来进行加、减、乘、除等运算,并且可以控制舍入模式,避免浮点数运算中的精度损失问题。 在项目描述中提到了“运用了类的特性”,这通常意味着项目中...

    JAVA中浮点数的运算

    这篇博客主要探讨了Java中浮点数(包括`float`和`double`类型)运算的特性、存在的问题以及如何应对这些挑战。 首先,Java中的`float`类型占用32位存储空间,它能表示大约6到7位十进制的有效数字,而`double`类型则...

    java学习资料第二章Java基本数据与运算

    ### Java基本数据与运算知识点详解 #### 2.1 数据类型及变量应用 ...通过以上练习,我们可以看到Java基本数据类型和运算符在实际问题解决中的应用。这些基础概念对于后续深入学习Java语言至关重要。

    DecimalFormat精度解决,商业运算精度问题

    ### DecimalFormat精度解决与商业运算精度问题 在进行财务计算或者商业运算时,精度问题往往成为影响最终结果准确性的关键因素之一。特别是在Java这样的语言环境中,由于其内部采用二进制浮点数表示小数的方式,这...

    java实现的四则运算

    在Java编程语言中,四则运算(加法、减法、乘法和除法)是基本的操作,它们在各种计算和逻辑处理中扮演着至关重要的角色。本项目旨在通过Java实现这些基本运算,并提供了一个强大的工具,对于学习和理解Java编程的...

    Java 实例 - 数字求和运算源代码-详细教程.zip

    在数字求和运算中,我们主要关注基本数据类型,如`int`(整型)和`double`(双精度浮点型)。`int`用于存储整数,而`double`则用于存储带有小数点的数值。在这个实例中,我们将使用`int`类型来存储我们的数字和。 ...

    java运算java运算.doc

    Java 运算精度问题与解决方案 在 Java 中,对于浮点数的运算存在精度问题,这是由于浮点数的计算是非精确计算的。这种问题在财务应用中非常重要,因为它可能导致严重的财务错误。 问题描述 在 Java 中,浮点数的...

    Java编写的大整数四则运算

    通过自定义的`Test1`和`Test2`类,我们不仅可以高效地处理大整数的四则运算,还能准确地求出最大公约数和最小公倍数,这对于需要处理超大数据集或高精度计算的场景尤为重要。这种实现方式不仅加深了我们对大整数运算...

    Java版计算器支持四则混合运算.+-*/()

    总的来说,这个Java版计算器项目涵盖了基本的算术运算、数据类型处理、字符串解析、栈数据结构的应用以及异常处理等多个Java编程核心概念,是学习和巩固编程技能的一个好练习。通过实际编写和测试这个计算器,开发者...

    bignumber.min.js下载

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

    四则运算用java实现

    在Java编程语言中,四则运算(加法、减法、乘法和除法)是基本的操作,它们广泛应用于各种计算场景。以下是对标题“四则运算用java实现”及描述“自己写的一个测试过的关于四则运算的java例子,可以处理小数”的详细...

    java基础--4.常用类-6.数字

    总之,Java中的数字处理涵盖了许多方面,从基本的数据类型到复杂的数学运算,再到高精度计算,都是Java程序员必备的知识点。理解并熟练运用这些概念,能帮助我们编写出高效且准确的代码。在实际编程中,根据需求选择...

    高精度运算_高精度运算_

    - **科学计算**:在天文学、物理学等领域,大数字运算用于模拟宇宙、粒子碰撞等。 - **金融计算**:银行和金融机构需要处理高精度的货币计算,确保财务数据的精确性。 - **密码学**:公钥加密算法如RSA依赖大整数...

    高精度加减计算(链表)

    在高精度加法中,我们需要处理两个大整数的和。首先,我们将这两个大整数表示为字符串,然后创建两个双向链表,每个链表的节点代表字符串中的一个数字。链表的头部是最低有效位,尾部是最高有效位。接着,我们从链表...

    计算机精度问题(Double)

    双精度浮点数(Double)在计算机中通常按照IEEE 754标准进行存储和运算,它提供了大约15到16位的有效数字,总共有64位,其中1位用于符号,11位用于指数,剩下52位用于尾数。这种表示方式使得双精度浮点数可以在很大...

    Java语言基础实验报告.pdf

    通过实验,学生可以了解Java语言的算术运算规则和精度问题。 4. 移位运算实验 本实验中,学生需要编写一个Java程序,展示移位运算的使用。通过实验,学生可以了解移位运算的规则和使用。 5. 运算赋值实验 本实验中...

    实验2 Java语言基础实验.doc

    实验内容包括局部变量与 final 变量、基本数据类型与转换、算术运算的精度问题、移位运算、运算赋值、短路逻辑运算、输出 Unicode 特定区间的字符、分析输入的数字等多个方面。 一、Java 语言基础知识点 1. Java ...

    超大数据,高精度加法和高精度阶乘运算

    在编程领域,尤其是在处理数值计算时,我们经常...这种方法虽然简单易懂,但在效率上可能不如专门的大数运算库,如C++中的`&lt;gmp&gt;`库或Java中的`BigInteger`类。在实际开发中,应根据项目需求和性能要求选择合适的方法。

    java数字类型转换

    根据提供的文件信息,我们可以深入探讨“Java数字类型转换”这一主题,特别是如何在GUI(图形用户界面)环境中进行整型与浮点型之间的转换。 ### Java数字类型概述 Java中的数字类型分为两大类:整型和浮点型。...

Global site tag (gtag.js) - Google Analytics