BigDecimal除法函数保留小数和四舍五入

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BigDecimal除法函数保留小数和四舍五入相关的知识,希望对你有一定的参考价值。

参考技术A 商=被除数.devide(除数,保留小数位数,精确方法)
120/100 ,150/100 ,180/100 值均为2

ROUND_CEILING: 舍位时往正无穷方向移动 1.1-> 2 1.5-> 2 1.8-> 2 -1.1-> -1 -1.5-> -1 -1.8-> -1
ROUND_DOWN:向0的方向移动1.1-> 1 1.5-> 1 1.8-> 1 -1.1-> -1 -1.5-> -1 -1.8> -1
ROUND_FLOOR:与CEILING相反,往负无穷 1.1-> 1 1.5-> 1 1.8-> 1 -1.1-> -2 -1.5-> -2 -1.8-> -2
ROUND_HALF_DOWN:以5为分界线,或曰五舍六入1.5-> 1 1.6-> 1 -1.5-> -1 -1.6-> -2
ROUND_HALF_EVEN:同样以5为分界线,如果是5,则前一位变偶数1.15-> 1.2 1.16-> 1.2 1.25-> 1.2 1.26-> 1.3
ROUND_HALF_UP:最常见的四舍五入
ROUND_UNNECESSARY:无需舍位
ROUND_UP:与ROUND_DOWN,远离0的方向1.1-> 2 1.5-> 2 1.8-> 2 -1.1-> -2 -1.5-> -2 -1.8-> -2

BigDecimal的用法详解(保留两位小数,四舍五入,数字格式化,科学计数法转数字,数字里的逗号处理)

一、简介

    Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

二、构造器描述

BigDecimal(int)       创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
BigDecimal(long)    创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。

三、方法描述

add(BigDecimal)        BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal)  BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal)     BigDecimal对象中的值相除,然后返回这个对象。
toString()                将BigDecimal对象的数值转换成字符串。
doubleValue()          将BigDecimal对象中的值以双精度数返回。
floatValue()             将BigDecimal对象中的值以单精度数返回。
longValue()             将BigDecimal对象中的值以长整数返回。
intValue()               将BigDecimal对象中的值以整数返回。

四、常用方法

4.1、保留两位小数

  1. /** 
  2.  * 保留两位小数 
  3.  */  
  4. @org.junit.Test  
  5. public void formatTest() {  
  6.     double num=13.154215;  
  7.   
  8.     //方式一  
  9.     DecimalFormat df1 = new DecimalFormat("0.00");  
  10.     String str = df1.format(num);  
  11.     System.out.println(str);  //13.15  
  12.   
  13.     //方式二  
  14.     // #.00 表示两位小数 #.0000四位小数  
  15.     DecimalFormat df2 =new DecimalFormat("#.00");  
  16.     String str2 =df2.format(num);  
  17.     System.out.println(str2);  //13.15  
  18.   
  19.     //方式三  
  20.     //%.2f %. 表示 小数点前任意位数   2 表示两位小数 格式后的结果为f 表示浮点型  
  21.     String result = String.format("%.2f", num);  
  22.     System.out.println(result);  //13.15  
  23. }  

String.formate用法详解:

  1.     @Test  
  2.     public void test1() { //4.1541483776749997E9  
  3.         double a = 4887233385.5;  
  4.         double b = 0.85;  
  5.           
  6.         System.out.println("result1-->"+a*b);  // result1-->4.1541483776749997E9  
  7.           
  8.         BigDecimal a1 = new BigDecimal(a);  
  9.         BigDecimal b1 = new BigDecimal(b);  
  10.           
  11.         System.out.println("result2-->"+a1.multiply(b1));//result2-->4154148377.674999891481619无限不循环  
  12.           
  13.         BigDecimal aBigDecimal = new BigDecimal(String.valueOf(a));  
  14.         BigDecimal bBigDecimal = new BigDecimal(String.valueOf(b));  
  15.           
  16.         // 或者下面这种写法  
  17. //      BigDecimal aBigDecimal = new BigDecimal(Double.toString(a));  
  18. //      BigDecimal bBigDecimal = new BigDecimal(Double.toString(b));  
  19.       
  20.         System.out.println("result3-->"+aBigDecimal.multiply(bBigDecimal)); //result3-->4154148377.675  
  21.   
  22.     }  

4.2、四舍五入

  1. /** 
  2.  * 四舍五入 
  3.  */  
  4. @Test  
  5. public void test2() {  
  6.     double num = 111231.5585;  
  7.     BigDecimal b = new BigDecimal(num);  
  8.     //保留2位小数  
  9.     double result = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
  10.     System.out.println(result);  //111231.56  
  11. }  

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则向下舍

setScaler(1,BigDecimal.ROUND_CEILING)接近正无穷大的舍入

setScaler(1,BigDecimal.ROUND_FLOOR)接近负无穷大的舍入,数字>0和ROUND_UP作用一样,数字<0和ROUND_DOWN作用一样

setScaler(1,BigDecimal.ROUND_HALF_EVEN)向最接近的数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。


注释:
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
4.3、格式化

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

  1. /** 
  2.  * 格式化 
  3.  */  
  4. @Test  
  5. public void test3() {  
  6.     NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用  
  7.     NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用  
  8.     percent.setMaximumFractionDigits(3); //百分比小数点最多3位  
  9.   
  10.     BigDecimal loanAmount = new BigDecimal("150.48"); //贷款金额  
  11.     BigDecimal interestRate = new BigDecimal("0.008"); //利率  
  12.     BigDecimal interest = loanAmount.multiply(interestRate); //相乘  
  13.   
  14.     System.out.println("贷款金额:\t" + currency.format(loanAmount)); //贷款金额: ¥150.48  
  15.     System.out.println("利率:\t" + percent.format(interestRate));  //利率: 0.8%  
  16.     System.out.println("利息:\t" + currency.format(interest)); //利息: ¥1.20  
  17. }  

  1. @Test  
  2. public void test3() {  
  3.     DecimalFormat df = new DecimalFormat();  
  4.     double data = 1234.56789//格式化之前的数字  
  5.   
  6.     //1、定义要显示的数字的格式(这种方式会四舍五入)  
  7.     String style = "0.0";  
  8.     df.applyPattern(style);  
  9.     System.out.println("1-->" + df.format(data));  //1234.6  
  10.   
  11.     //2、在格式后添加诸如单位等字符  
  12.     style = "00000.000 kg";  
  13.     df.applyPattern(style);  
  14.     System.out.println("2-->" + df.format(data));  //01234.568 kg  
  15.   
  16.   
  17.     //3、 模式中的"#"表示如果该位存在字符,则显示字符,如果不存在,则不显示。  
  18.     style = "##000.000 kg";  
  19.     df.applyPattern(style);  
  20.     System.out.println("3-->" + df.format(data));  //1234.568 kg  
  21.   
  22.     //4、 模式中的"-"表示输出为负数,要放在最前面  
  23.     style = "-000.000";  
  24.     df.applyPattern(style);  
  25.     System.out.println("4-->" + df.format(data)); //-1234.568  
  26.   
  27.   
  28.     //5、 模式中的","在数字中添加逗号,方便读数字  
  29.     style = "-0,000.0#";  
  30.     df.applyPattern(style);  
  31.     System.out.println("5-->" + df.format(data));  //5-->-1,234.57  
  32.   
  33.   
  34.     //6、模式中的"E"表示输出为指数,"E"之前的字符串是底数的格式,  
  35.     // "E"之后的是字符串是指数的格式  
  36.     style = "0.00E000";  
  37.     df.applyPattern(style);  
  38.     System.out.println("6-->" + df.format(data));  //6-->1.23E003  
  39.   
  40.   
  41.     //7、 模式中的"%"表示乘以100并显示为百分数,要放在最后。  
  42.     style = "0.00%";  
  43.     df.applyPattern(style);  
  44.     System.out.println("7-->" + df.format(data));  //7-->123456.79%  
  45.   
  46.   
  47.     //8、 模式中的"\u2030"表示乘以1000并显示为千分数,要放在最后。  
  48.     style = "0.00\u2030";  
  49.     //在构造函数中设置数字格式  
  50.     DecimalFormat df1 = new DecimalFormat(style);  
  51.     //df.applyPattern(style);  
  52.     System.out.println("8-->" + df1.format(data));  //8-->1234567.89‰  
  53. }  

4.4、BigDecimal比较

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

  1. /** 
  2.  * 注意不能使用equals方法来比较大小。 
  3.  * 
  4.  * 使用BigDecimal的坏处是性能比double和float差,在处理庞大,复杂的运算时尤为明显,因根据实际需求决定使用哪种类型。 
  5.  */  
  6. @Test  
  7. public void test4() {  
  8.     BigDecimal a = new BigDecimal("1");  
  9.     BigDecimal b = new BigDecimal("2");  
  10.     BigDecimal c = new BigDecimal("1");  
  11.     int result1 = a.compareTo(b);  
  12.     int result2 = a.compareTo(c);  
  13.     int result3 = b.compareTo(a);  
  14.   
  15.     System.out.println(result1);  //-1  
  16.     System.out.println(result2);  //0  
  17.     System.out.println(result3);  //1  
  18. }  

4.5、科学计数法

    有些项目可能会涉及到从Excel导入数据,但如果Excel里单元格类型为数值,但内容数据太长时(如银行账号),导入时,会默认读取为科学计数法,用以下代码便轻松解决。

  1. @Test  
  2. public void test5() {  
  3.     BigDecimal bd = new BigDecimal("3.40256010353E11");  
  4.     String result = bd.toPlainString();  
  5.     System.out.println(result);  //340256010353  
  6. }  

4.6、java中价格的数字中间有逗号的处理

  1. @Test  
  2. public void test1() {  
  3.     java.util.StringTokenizer st = new StringTokenizer( "123,456,789"",");  
  4.     StringBuffer sb = new StringBuffer();  
  5.     while(st.hasMoreTokens())   {  
  6.         sb.append(st.nextToken());  
  7.     }  
  8.     System.out.println(sb);  //123456789  
  9. }  
  10.   
  11. @Test  
  12. public void test2() {  
  13.     String str = "123,456,789";  
  14.     str = str.replace(",""");  
  15.     System.out.println(str);  //123456789  
  16. }  

4.7.精确计算

  1. double value1=1.00;  
  2. String value2 = "1.00";  
  3. BigDecimal b1 = new BigDecimal(Double.valueOf(value1));  
  4. BigDecimal b1 = new BigDecimal(String.valueOf(value2));  
  5.   
  6.  public BigDecimal add(BigDecimal value);                        //加法  
  7.  public BigDecimal subtract(BigDecimal value);                   //减法   
  8.  public BigDecimal multiply(BigDecimal value);                   //乘法  
  9.  public BigDecimal divide(BigDecimal value);                     //除法  
下面是一个工具类,该工具类提供加,减,乘,除运算。
  1. public class Arith {  
  2.     /** 
  3.      * 提供精确加法计算的add方法 
  4.      * @param value1 被加数 
  5.      * @param value2 加数 
  6.      * @return 两个参数的和 
  7.      */  
  8.     public static double add(double value1,double value2){  
  9.         BigDecimal b1 = new BigDecimal(Double.valueOf(value1));  
  10.         BigDecimal b2 = new BigDecimal(Double.valueOf(value2));  
  11.         return b1.add(b2).doubleValue();  
  12.     }  
  13.       
  14.     /** 
  15.      * 提供精确减法运算的sub方法 
  16.      * @param value1 被减数 
  17.      * @param value2 减数 
  18.      * @return 两个参数的差 
  19.      */  
  20.     public static double sub(double value1,double value2){  
  21.         BigDecimal b1 = new BigDecimal(Double.valueOf(value1));  
  22.         BigDecimal b2 = new BigDecimal(Double.valueOf(value2));  
  23.         return b1.subtract(b2).doubleValue();  
  24.     }  
  25.       
  26.     /** 
  27.      * 提供精确乘法运算的mul方法 
  28.      * @param value1 被乘数 
  29.      * @param value2 乘数 
  30.      * @return 两个参数的积 
  31.      */  
  32.     public static double mul(double value1,double value2){  
  33.         BigDecimal b1 = new BigDecimal(Double.valueOf(value1));  
  34.         BigDecimal b2 = new BigDecimal(Double.valueOf(value2));  
  35.         return b1.multiply(b2).doubleValue();  
  36.     }  
  37.       
  38.     /** 
  39.      * 提供精确的除法运算方法div 
  40.      * @param value1 被除数 
  41.      * @param value2 除数 
  42.      * @param scale 精确范围 
  43.      * @return 两个参数的商 
  44.      * @throws IllegalAccessException 
  45.      */  
  46.     public static double div(double value1,double value2,int scale) throws IllegalAccessException{  
  47.         //如果精确范围小于0,抛出异常信息  
  48.         if(scale<0){           
  49.             throw new IllegalAccessException("精确度不能小于0");  
  50.         }  
  51.         BigDecimal b1 = new BigDecimal(Double.valueOf(value1));  
  52.         BigDecimal b2 = new BigDecimal(Double.valueOf(value2));  
  53.         return b1.divide(b2, scale).doubleValue();      
  54.     }  
  55. }  














































以上是关于BigDecimal除法函数保留小数和四舍五入的主要内容,如果未能解决你的问题,请参考以下文章

SQL中decimal和numeric为啥会自动四舍五入啊?我是想保留有小数的怎么办?

java bigdecimal 四舍五入

java 保留两位小数点

BigDecimal除法问题

BigDecimal 高精度计算 熟悉扩展,java除法保留小数问题

java中 BigDecimal的类型的除法