知识路线:
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类为所有的大数
字的处理提供了相应的数学运算操作方法
Java中的BigDecimal类用于解决浮点数计算时的精度问题。通过使用BigDecimal的构造函数、加减乘除等方法,可以进行精确的实数运算。在使用时,优先使用String构造方法以避免精度损失,运算后可通过doubleValue等方法转换为基本类型。
3587

被折叠的 条评论
为什么被折叠?



