Java中用于处理实数精确运算

Java中的BigDecimal类用于解决浮点数计算时的精度问题。通过使用BigDecimal的构造函数、加减乘除等方法,可以进行精确的实数运算。在使用时,优先使用String构造方法以避免精度损失,运算后可通过doubleValue等方法转换为基本类型。
摘要由CSDN通过智能技术生成
知识路线:
BigDecimal类的概念介绍(作用)-->了解这个类的用法(构造函数,常用方法,代码的运用效果)-->知识总结

问题描述:实数的精确运算与保留精度问题
原因: 我们的计算机是二进制的。浮点数没有办法是用 二进制进行精确表示 。我们的CPU 表示浮点数由两个部分组 :指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。如: 2.4 的二进制表示并非就是精确的 2.4 。反而最为接近的二进制表示是  2.3999999999999999 。浮点数的值实际上是由一个特定的数学公式计算得到的。

1.BigDecimal类控制浮点数的计算精度
位置:java软件包中的java.math中可提供用于执行 任意精度整数的算法(BigInteger) 任意精度小数算法(BigDecimal) 的类。

 在使用 BigDecimal 类来进行计算的时候,主要分为以下步骤:
              1、用 String 或者 double 变量 构建 BigDecimal 对象。(优先采用String)
             2、通过调用 BigDecimal 的加,减,乘,除等相应的方法进行算术运算。
             3、把 BigDecimal 对象转换成 float double int 等类型。
注意事项:
1、 参数类型为double的构造方法的结果有一定的不可预知性。 有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
      2、另一方面, String 构造方法是完全可预知的 :写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言, 通常建议优先使用 String构造方法
      3、 当double必须用作BigDecimal的源时 ,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用 Double.toString(double) 方法,然后使用 BigDecimal(String) 构造方法, 将double转换为String 。要获取该结果,请 使用static  valueOf(double) 方法。
例:
1.BigDecimal b1 = new BigDecimal(Double.toString(0.48)); 2 BigDecimal b2 = BigDecimal.valueOf(0.48);
Double.toString()是将一个double类型的实数转化成相应的字符串。
BigDecimal.valueOf()是将double类型转化为一个BigDecimal类型的对象。


对于常用的加,减,乘,除, BigDecimal 类提供了相应的成员方法。
public class Arith {
  /**
     * 提供精确加法计算的add方法
     * @param value1 被加数
      * @param value2 加数
     * @return 两个参数的和
     */
    public static double add(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
       return b1.add(b2).doubleValue();
    }
     
    /**
     * 提供精确减法运算的sub方法
      * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
      */
     public static double sub(double value1,double value2){
         BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
         return b1.subtract(b2).doubleValue();
     }
     
    /**
      * 提供精确乘法运算的mul方法
     * @param value1 被乘数
     * @param value2 乘数
      * @return 两个参数的积
      */
     public static double mul(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
         BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.multiply(b2).doubleValue();
    }
     
     /**
      * 提供精确的除法运算方法div
     * @param value1 被除数
      * @param value2 除数
      * @param scale 精确范围
      * @return 两个参数的商
      * @throws IllegalAccessException
      */
     public static double div(double value1,double value2,int scale) throws IllegalAccessException{
        //如果精确范围小于0,抛出异常信息
         if(scale<0){         
             throw new IllegalAccessException("精确度不能小于0");
         }
         BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
         BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
         return b1.divide(b2, scale).doubleValue();    
     }
 }



进行相应的计算后,我们可能需要 BigDecimal 对象转换成相应的基本数据类型的变量,可以使用 floatValue() doubleValue() 等方法。

  
下面是一个工具类,该工具类提供加,减,乘,除运算。






源代码的应用:
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Scanner;

import com.sun.org.apache.xerces.internal.impl.dv.xs.DecimalDV;

/**
* 求圆的面积,结果保留7位小数,四舍五入
* @author Dragon
* time:2017/2/13
*/

public class Main{
public static void main(String[] args) throws IOException{
Scanner in=new Scanner(System.in);
int r=in.nextInt();
double area=Math.PI*r*r;
//对结果进行精度控制
BigDecimal result=new BigDecimal(Double.toString(area));
System.out.println(result.setScale(7,BigDecimal.ROUND_HALF_UP));
}
}
运行结果:


用法总结:
BigDecimal用于处理实数的精度以及实数的运算问题。
1.构造函数一般用String和double这两种,优先用String类型的入口参数。
2.了解BigDecimal这个类常用的方法:加减乘除,精度更改
3.运算后的类型是BigDecimal,要转化成基本类型用到doublevalue,floatvalue等方法。


DecimalFormat类用于格式化数字、Math类为各种数学计算提供了具方法、Random
为Java处理随机数问题提供了各种方法、BigInteger与BigDecimal类为所有的大数
字的处理提供了相应的数学运算操作方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值