今天格式化数字的时候偶遇前同事写的关于BigDecimal的使用。之前不甚了解。网上找到两篇比较靠谱的文章,一篇介绍了格式化小数点常用的setScale()方法,另一篇介绍了BigDecimal的一些基本概念。
基本使用参考第一篇即可。
=========================================
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则scale就是3.
scale()就是BigDecimal类中的方法啊。
比如:BigDecimalb = new BigDecimal("123.456");
b.scale(),返回的就是3.
2:
roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。
3:
pubilc BigDecimal divide(BigDecimal divisor, int scale, introundingMode)
的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!
4:对于一般add、subtract、multiply方法的小数位格式化如下:
BigDecimal mData = newBigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("mData=" + mData);
----结果:----- mData=9.66
==========================================
一提到Java里面的商业计算,我们都知道不能用float和double,因为他们无法进行精确计算。但是Java的设计者给编程人员提供了一个很有用的类BigDecimal,他可以完善float和double类无法进行精确计算的缺憾。BigDecimal类位于java.maths类包下。首先我们来看下如何构造一个BigDecimal对象。它的构造函数很多,我挑最常用的两个来演示一下:一个就是BigDecimal(double val),另一个就是BigDecimal(String str)。这两个看上去没什么太大区别,但是正像API描述中说的那样:
- /*The results of this constructor can be somewhat unpredictable. One might assume that
- new BigDecimal(.1) is exactly equal to .1, but it is actually equal
- to .1000000000000000055511151231257827021181583404541015625. This is so because .1
- cannot be represented exactly as a double (or, for that matter, as a binary fraction
- of any finite length). Thus, the long value that is being passed in to the constructor
- is not exactly equal to .1, appearances nonwithstanding.
- The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal
- (".1") is exactly equal to .1, as one would expect. Therefore, it is generally
- recommended that the (String) constructor be used in preference to this one.*/
也就是说利用double作为参数的构造函数,无法精确构造一个BigDecimal对象,需要自己指定一个上下文的环境,也就是指定精确位。而利用String对象作为参数传入的构造函数能精确的构造出一个BigDecimal对象。请看下面的代码:
- import java.math.*;
- public class TestBigDecimal {
- public static void main(String args[]){
- BigDecimal bd = new BigDecimal("10.123");
- BigDecimal bd1 = new BigDecimal(10.123);
- System.out.println(bd +"/n"+ bd1);
- }
- }
输出:
- 10.123
- 10.1229999999999993320898283855058252811431884765625
所以我们在选择构造函数时,要看具体需求而定。
另外,很多人会问到怎么将基本类型,如int,float,double,long,和BigDecimal对象相互转换。很简单:
基本类型通过构造函数转换成对应的BigDecimal对象,而BigDecimal类提供了诸如intValue(), floatValue(), doubleValue(), longValue()方法来将BigDecimal对象转换成对应的值。
关于BigDecimal是如何计算的,我以论坛中一个人的提问帖子为例,来简单的写出BigDecimal的运算方法。题目是:李白无事街上走,提壶去买酒。遇店加一倍,见花喝一斗,五遇花和店,喝光壶中酒,试问李白壶中原有多少斗酒?
这道题应该是从后往前推,并且要逆运算,最后得出原有酒的体积。
- import java.math.*;
- public class Libai {
- public static void main(String args[]){
- BigDecimal volumn = new BigDecimal("0");
- for (int i=0; i<5; i++){
- volumn = volumn.add(new BigDecimal("1"));
- volumn = volumn.divide(new BigDecimal("2"));
- }
- System.out.print(volumn);
- }
- }
结果:
- 0.96875