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对象中的值以整数返回。 negate() 将BigDecimal对象中的值取反返回。
三.用法详解
1.加减乘除运算
/** * 数字计算 */ @Test public void testCount() { BigDecimal num1 = new BigDecimal("5"); BigDecimal num2 = new BigDecimal("5"); BigDecimal num3 = null; //加法 num3 = num1.add(num2); System.out.println("和 是:" + num3);//10 //减法 num3 = num1.subtract(num2); System.out.println("差 是:" + num3);//0 //乘法 num3 = num1.multiply(num2); System.out.println("积 是:" + num3);//25 //除法 num3 = num1.divide(num2); System.out.println("商 是:" + num3);//1 }
2.数字比较
/** * 数字比较 * 注意不能使用equals方法来比较大小。 * 使用BigDecimal的坏处是性能比double和float差,在处理庞大,复杂的运算时尤为明显,因根据实际需求决定使用哪种类型。 */ @Test public void testCompare() { BigDecimal num1 = new BigDecimal("0"); BigDecimal num2 = new BigDecimal("1"); BigDecimal num3 = new BigDecimal("2"); BigDecimal num = new BigDecimal("1"); //用做比较的值 System.out.println(num1.compareTo(num)); //前面 小于 后面 时,返回 -1 System.out.println(num2.compareTo(num)); //前面 等于 后面 时,返回 0 System.out.println(num3.compareTo(num)); //前面 大于 后面 时,返回 1 }
3.格式化小数点
/** * BigDecimal.setScale()方法用于格式化小数点 */ @Test public void testScale() { BigDecimal num = new BigDecimal("2.35"); //setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 System.out.println("BigDecimal.ROUND_UP 是:" + num.setScale(1, BigDecimal.ROUND_UP)); //setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,2.35会变成2.3 System.out.println("BigDecimal.ROUND_DOWN 是:" + num.setScale(1, BigDecimal.ROUND_DOWN)); //setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4 System.out.println("BigDecimal.ROUND_HALF_UP 是:" + num.setScale(1, BigDecimal.ROUND_HALF_UP)); //setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍 System.out.println("BigDecimal.ROUND_HALF_DOWN 是:" + num.setScale(1, BigDecimal.ROUND_HALF_DOWN)); //setScaler(1,BigDecimal.ROUND_CEILING)接近正无穷大的舍入 System.out.println("BigDecimal.ROUND_CEILING 是:" + new BigDecimal("2.31").setScale(1, BigDecimal.ROUND_CEILING));//2.4 //setScaler(1,BigDecimal.ROUND_FLOOR)接近负无穷大的舍入,数字>0和ROUND_UP作用一样,数字<0和ROUND_DOWN作用一样 System.out.println("BigDecimal.ROUND_FLOOR 是:" + new BigDecimal("-2.31").setScale(1, BigDecimal.ROUND_FLOOR));//-2.4 //setScaler(1,BigDecimal.ROUND_HALF_EVEN)向最接近的数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。 System.out.println("BigDecimal.ROUND_HALF_EVEN 是:" + new BigDecimal("2.33").setScale(1, BigDecimal.ROUND_HALF_EVEN));//2.3 }
4.negate() 将BigDecimal对象中的值取反返回。
@Test public void testNegate() { System.out.println(new BigDecimal("10"));//10 System.out.println(new BigDecimal("10").negate());//-10 System.out.println(new BigDecimal("30").add(new BigDecimal("10").negate()));//20 }
4.double类型会有精度丢失问题
/** * double类型会有精度丢失问题 */ @Test public void testLostAccuracy() { //初始化时用double类型会有精度丢失问题 BigDecimal totalAmount = new BigDecimal(1); totalAmount = totalAmount.add(new BigDecimal(0.59)); System.out.println(totalAmount);//1.58999999999999996891375531049561686813831329345703125 //使用String可以避免精度丢失问题 BigDecimal totalAmount2 = new BigDecimal(1); totalAmount2 = totalAmount2.add(new BigDecimal("0.59")); System.out.println(totalAmount2);//1.59 }
5.格式化
/** * 格式化 */ @Test public void testFormat() { NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用 NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用 percent.setMaximumFractionDigits(3); //百分比小数点最多3位 BigDecimal loanAmount = new BigDecimal("150.48"); //贷款金额 BigDecimal interestRate = new BigDecimal("0.008"); //利率 BigDecimal interest = loanAmount.multiply(interestRate); //相乘 System.out.println("贷款金额:\t" + currency.format(loanAmount)); //贷款金额: ¥150.48 System.out.println("利率:\t" + percent.format(interestRate)); //利率: 0.8% System.out.println("利息:\t" + currency.format(interest)); //利息: ¥1.20 DecimalFormat df = new DecimalFormat(); double data = 1234.56789; //格式化之前的数字 //1、定义要显示的数字的格式(这种方式会四舍五入) String style = "0.0"; df.applyPattern(style); System.out.println("1-->" + df.format(data)); //1234.6 //2、在格式后添加诸如单位等字符 style = "00000.000 kg"; df.applyPattern(style); System.out.println("2-->" + df.format(data)); //01234.568 kg //3、 模式中的"#"表示如果该位存在字符,则显示字符,如果不存在,则不显示。 style = "##000.000 kg"; df.applyPattern(style); System.out.println("3-->" + df.format(data)); //1234.568 kg //4、 模式中的"-"表示输出为负数,要放在最前面 style = "-000.000"; df.applyPattern(style); System.out.println("4-->" + df.format(data)); //-1234.568 //5、 模式中的","在数字中添加逗号,方便读数字 style = "-0,000.0#"; df.applyPattern(style); System.out.println("5-->" + df.format(data)); //5-->-1,234.57 //6、模式中的"E"表示输出为指数,"E"之前的字符串是底数的格式, // "E"之后的是字符串是指数的格式 style = "0.00E000"; df.applyPattern(style); System.out.println("6-->" + df.format(data)); //6-->1.23E003 //7、 模式中的"%"表示乘以100并显示为百分数,要放在最后。 style = "0.00%"; df.applyPattern(style); System.out.println("7-->" + df.format(data)); //7-->123456.79% //8、 模式中的"\u2030"表示乘以1000并显示为千分数,要放在最后。 style = "0.00\u2030"; //在构造函数中设置数字格式 DecimalFormat df1 = new DecimalFormat(style); //df.applyPattern(style); System.out.println("8-->" + df1.format(data)); //8-->1234567.89‰ }
6.科学计数法
/** * 科学计数法 */ @Test public void testScientificNotation() { BigDecimal bd = new BigDecimal("3.40256010353E11"); String result = bd.toPlainString(); System.out.println(result); //340256010353 }
7.java中价格的数字中间有逗号的处理
/** * java中价格的数字中间有逗号的处理 */ @Test public void test6() { java.util.StringTokenizer st = new StringTokenizer("123,456,789", ","); StringBuffer sb = new StringBuffer(); while (st.hasMoreTokens()) { sb.append(st.nextToken()); } System.out.println(sb); //123456789 String str = "123,456,789"; str = str.replace(",", ""); System.out.println(str); //123456789 }
转自:https://blog.51cto.com/u_16099336/7537612