`

解决Java中浮点型数据计算时产生的精度误差

阅读更多
关于double和float的精度问题,在进行数值运算时,如果有float或者double类型的浮点数参与计算时,偶尔会出现结果不准确的情况。
比如:
/**
 * 解决Float与Double类型进度不准确的问题
 * @author XiaoYun 2013-08-17
 */
public class PrecisionOfFloatAndDouble {
public static void main(String[] args) {
testUnPrecision();
}
 
/**
 * 不准确问题示例
 */
private static void testUnPrecision() {
System.out.println("--------Java自身的Double类型有精度损失----------");
System.out.println(0.05+0.01); //0.060000000000000005
System.out.println(1.0-0.54);  //0.45999999999999996
System.out.println(4.015*1000); //4014.9999999999995
System.out.println(12.3/100); //0.12300000000000001 
}
}
 
执行程序后,控制台打印出来的数据为:
--------Java自身的Double类型有精度损失----------
0.060000000000000005
0.45999999999999996
4014.9999999999995
0.12300000000000001
 
下面开始说解决方法:
    首先,解决思路为使用java.math.BigDecimal类。查看JDK提供的api,可以使用BigDecimal(String val)构造方法(因为使用该方法构造的结果是完全可以预知的),因为使用BigDecimal(double val)构建出来的结果具有一定的不可预见性,而,其中val=Double(或者Float).toString(double1);,在使用该类中对应的加减乘除等方法来计算,该类中还提供了许多的计算方法,比如同时计算出商和余数的方法divideAndRemainder(BigDecimal divisor),求商但是向下取(即如果商是3.5,那么就返回3)的方法
divideToIntegralValue(BigDecimal divisor)等,这些方法我也没有全部研究,只是研究了这么多,如果你有兴趣的话可以自己研究下。
 
计算工具类:    
package com.xiaoyun.test;
 
import java.math.BigDecimal;
 
/**
 * 消除加减乘除的精度
 * @author XiaoYun 2013-08-17
 */
public class ArithUtil {
/**
 * 加法运算
 * @param v1
 * @param v2
 * @return
 */
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
 
/**
 * 减法运算
 * @param v1
 * @param v2
 * @return
 */
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
 
/**
 * 乘法运算
 * @param v1
 * @param v2
 * @return
 */
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
 
/**
 * 除法运算
 * @param v1 被除数
 * @param v2 除数
 * @return 商
 */
public static double div(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2).doubleValue();
}
 
/**
 * 除法运算
 * @param v1 被除数
 * @param v2 除数
 * @return 商和余数
 */
public static BigDecimal[] divideAndRemainder(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
BigDecimal[] arr = b1.divideAndRemainder(b2);
return arr;
}
 
/**
 * 求商(向下舍入)
 * @param v1
 * @param v2
 * @return
 */
public static BigDecimal divideToIntegralValue(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
System.out.println("------------");
return b1.divideToIntegralValue(b2);
}
}
 
测试类:
package com.xiaoyun.test;
 
import java.math.BigDecimal;
 
 
/**
 * 解决Float与Double类型进度不准确的问题
 * @author XiaoYun 2013-08-17
 */
public class PrecisionOfFloatAndDouble {
public static void main(String[] args) {
testUnPrecision();
System.out.println("----------使用BigDecimal消除精度影响------------\n" + ArithUtil.add(0.05, 0.01));
System.out.println(ArithUtil.sub(1.0, 0.54));
System.out.println(ArithUtil.mul(4.015, 1000));
System.out.println(ArithUtil.div(12.3, 10));
//得到商和余数
BigDecimal[] arr = ArithUtil.divideAndRemainder(12.3, 10);
System.out.println("得到商和余数");
for (BigDecimal bigDecimal : arr) {
System.out.println(bigDecimal);
}
System.out.println(ArithUtil.divideToIntegralValue(4.5, 2));
}
 
/**
 * 不准确问题示例
 */
private static void testUnPrecision() {
System.out.println("--------Java自身的Double类型有精度损失----------");
System.out.println(0.05+0.01);
System.out.println(1.0-0.54);
System.out.println(4.015*1000);
System.out.println(12.3/100);
}
}
 
到此,浮点数京都的问题就解决了。但是究其原因,是浮点数在计算机中是无法进行准确表示的,比如0.1在计算机中只是一个近似值,因此对浮点数运算结果具有不可预见性。如果两个浮点操作数的误差就能相互抵消,计算结果就能正确。比如0.3+0.4。
 
0
6
分享到:
评论

相关推荐

    浮点型数据与IEEE754标准互转

    而在算法设计和调试时,了解内部表示可以帮助我们分析和解决精度误差。 总之,浮点型数据与IEEE754标准的互转是计算机科学中不可或缺的一部分。通过手动转换、编程语言内置函数或第三方库,我们可以灵活地在两种...

    Java数值计算算法编程

    统计分析在数据科学中占据核心地位,Java同样支持这方面的计算。通过Java的StatisticalSummary类可以计算基本统计量,如平均值、标准差等。对于更复杂的统计模型,可以借助Weka、 Smile或Java-ML等机器学习库。 在...

    java数值计算算法编程

    1. **基本数据类型与运算符**:Java提供了八种基本数据类型,包括整型(byte, short, int, long)、浮点型(float, double)以及布尔型(boolean)。在数值计算中,理解和掌握这些数据类型的范围、精度以及它们之间...

    Java与MySQL中小数保存问题解析.pptx.pptx

    在Java和MySQL中,处理小数时需要注意一系列与精度、数据类型选择以及运算准确性相关的问题。首先,让我们深入了解Java中小数的保存方式...在开发过程中,应充分考虑这些因素,以避免潜在的精度误差和数据不一致问题。

    Java四类八种数据类型

    ### Java四类八种数据类型 #### 一、逻辑型:`boolean` - **描述**:`boolean` 类型主要用于...特别是对于浮点型数据,需要注意其在运算过程中的精度损失问题,并采取适当的处理措施,以避免因误差而导致的错误结果。

    Java 基本语法(一)——数据类型

    本文将详细介绍Java中的基本数据类型,包括整型、浮点型、字符型以及布尔型。 #### 整型数据类型 Java支持四种整型数据类型:`byte`、`short`、`int` 和 `long`。 1. **`byte`**:占用1个字节(8位),取值范围为 -...

    2.数据类型与运算符1

    本节主要探讨了Java中的几种基本数据类型,包括整型、长整型、双精度浮点型和单精度浮点型。 首先,整型变量(int)是编程中最常见的数据类型之一,它用于存储整数值。在Java中,int类型占用4个字节,即32位,其...

    复习java基础.pdf

    1. 浮点型数据运算与精度问题:在Java中,浮点型数据(如`float`和`double`)在计算时可能会出现微小的误差。例如,`if(a+1.0=4.0)`这样的判断可能由于浮点运算的精度问题而导致误判。为避免此类问题,开发者应尽量...

    实例025 - 更精确地使用浮点数

    在编程领域,浮点数是数字计算中的重要组成部分,特别是在科学计算、图形处理以及各种需要进行高精度或低精度近似计算的场景中。标题"实例025 - 更精确地使用浮点数"提示我们,这个实例可能关注的是如何在编程中更...

    创建一个类(DoubleConverter),该类的作用是将一个字符串的值转换成浮点型(double)数值。

    根据给定的信息,本文将详细解释如何在Java中创建一个名为`DoubleConverter`的类,其功能是将字符串转换为浮点数(double)。本文将深入解析类的设计思路、实现细节以及潜在的问题处理方法。 ### 创建`...

    java_JAVA_WEB基本教程

    对于浮点型,由于存在精度误差,通常需要设定一个极小的正数作为误差范围进行比较。 #### 五、Java类与构造函数 类是Java中面向对象编程的核心概念,而构造函数则是用于初始化类的实例的重要方法。构造函数的命名与...

    javascript避免数字计算精度误差的方法详解

    但是你知道吗,同样的问题放在编程语言中,或许就不是想象中那么简单的事儿了。不信?我们先来看一段 JS。 var numA = 0.1; var numB = 0.2; alert( (numA + numB) === 0.3 ); 执行结果是 false。没错,当...

    Java面向对象的笔记.pdf

    因此,处理浮点数时要注意精度误差。 7. Java中的科学计数法 Java中的浮点数可以使用科学计数法表示,用e或E后跟10的幂次来表示,例如1.23E3表示1.23乘以10的3次方。 通过上述知识点的整合,我们可以全面了解Java...

    float型和double型数据的存储方式1

    本文主要探讨了浮点类型数据,即float和double在内存中的表示方式,以及由此产生的精度问题。 首先,浮点类型数据有两种主要形式:单精度(float)和双精度(double)。float在内存中占用32位,而double占用64位。这...

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

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

    Java 60道面试题和答案.docx

    - 浮点型计算可能产生微小误差,避免在布尔表达式中使用浮点型。可以使用BigDecimal类进行高精度浮点运算。 16. **程序结构**: - 顺序结构、选择结构(if-else)和循环结构(for, while)是程序的基本结构。 17...

    完整版高精度运算模块2.1版.rar

    1. **高精度计算**:模块采用了多位数表示法,能够进行超于常规浮点数精度的运算,确保在计算过程中避免因为浮点数精度限制而导致的误差积累。这对于需要极度精确结果的领域,如金融计算、物理模拟和航空航天等,至...

Global site tag (gtag.js) - Google Analytics