当前位置 : 主页 > 编程语言 > java >

BigDecimal

来源:互联网 收集:自由互联 发布时间:2022-07-22
java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。 在使用BigDecimal类来进行计算的时候,主要分为以下步骤: 1、用flo

java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

在使用BigDecimal类来进行计算的时候,主要分为以下步骤:

1、用float或者double变量构建BigDecimal对象。

             2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。

             3、把BigDecimal对象转换成float,double,int等类型。

 

Bigdecimal是无法直接用+-*/这些符号进行计算的,它有自己的运算方法,如下;

 

public BigDecimal add(BigDecimal value); //加法
public BigDecimal subtract(BigDecimal value); //减法
public BigDecimal multiply(BigDecimal value); //乘法
public BigDecimal divide(BigDecimal value); //除法


可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。
BigDecimal一共有4个构造方法
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象
BigDecimal b2 = BigDecimal.valueOf(0.48);

toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。

 

可以使用floatValue(),doubleValue()等方法。

 

可以在运算前后对其进行精度的设置:如下文:

BigDecimal.setScale()方法用于格式化小数点
setScale(1)表示保留一位小数,默认用四舍五入方式
setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3
setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4
setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4 适用元角分模式
setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍

 

 

注释:

1:scale指的是你小数点后的位数。比如123.456则score就是3.
score()就是BigDecimal类中的方法啊。
比如:BigDecimal b = new BigDecimal("123.456");

b.scale(),返回的就是3.

 

2:roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。

3:pubilc BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!

 

4:对于一般add、subtract、multiply方法的小数位格式化如下:

BigDecimal mData = new BigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
        System.out.println("mData=" + mData);

 

----结果:----- mData=9.66

 

========================================================================================

 

精度设置,为什么会设置精度,给大家看个效果

 

BigDecimal abig=new BigDecimal(10.0);

BigDecimal bbig=new BigDecimal(9.1);

BigDecimal cbig=new BigDecimal(8.9);

System.out.println(abig.subtract(bbig));

System.out.println(abig.subtract(cbig));

结果如下:

0.9000000000000003552713678800500929355621337890625

1.0999999999999996447286321199499070644378662109375

 

并不是我们希望看到的0.9和1.1,原因就是转成二进制的时候会有精度问题,导致这样的结果。所以我们可以在运算的时候加精度,也可以在实例化BigDecimal的时候用字符串。

 

设置精度的方法:

System.out.println(abig.subtract(bbig).setScale(2, BigDecimal.ROUND_HALF_UP));

System.out.println(abig.subtract(cbig).setScale(2, BigDecimal.ROUND_HALF_UP));
这样设置两位精度就可以啦
0.90

1.10

 

取反

因为Bigdecimal是无法直接用+-*/这些符号进行计算的,所以取反的时候也需要一个单独的方法来实现:

System.out.println(abig.negate());  

这样就会拿到它的相反数了:

-10.0 

========================================================================================

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

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();
}
}

 

格式化及例子
由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。

以利用BigDecimal对货币和百分比格式化为例。首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。

 

public static void main(String[] args) {

NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用

NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用

percent.setMaximumFractionDigits(3); //百分比小数点最多3位

BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额

BigDecimal interestRate = new BigDecimal("0.008"); //利率

BigDecimal interest = loanAmount.multiply(interestRate); //相乘

System.out.println("贷款金额:\t" + currency.format(loanAmount));

System.out.println("利率:\t" + percent.format(interestRate));

System.out.println("利息:\t" + currency.format(interest));
}


运行结果如下:

贷款金额: ¥15,000.48

利率: 0.8%

利息: ¥120.00

 


BigDecimal比较
BigDecimal是通过使用compareTo(BigDecimal)来比较的,具体比较情况如下:

public static void main(String[] args) {

BigDecimal a = new BigDecimal("1");

BigDecimal b = new BigDecimal("2");

BigDecimal c = new BigDecimal("1");

int result1 = a.compareTo(b);

int result2 = a.compareTo(c);

int result3 = b.compareTo(a);

System.out.println(result1);

System.out.println(result2);

System.out.println(result3);

}

打印结果是:-1、0、1,即左边比右边数大,返回1,相等返回0,比右边小返回-1。

 

注意不能使用equals方法来比较大小。

使用BigDecimal的坏处是性能比double和float差,在处理庞大,复杂的运算时尤为明显,因根据实际需求决定使用哪种类型。

 

Creating a NumberFormat

Creating a ​​NumberFormat​​​ ​​Locale​​ is done like this:

Locale locale = new Locale("da", "DK");

NumberFormat numberFormat = NumberFormat.getInstance(locale);

和Locale  一起用会格式化一些国家的金额。

详细API :http://tutorials.jenkov.com/java-internationalization/numberformat.html

 

 



上一篇:关于字符串的分割问题
下一篇:没有了
网友评论