BigDecimal通常用于精确的商业计算,处理较大数据的运算,BigDecimal不用使用简单的+-*/等,需要用类自己的方法运算,普通float和double保存的时候就会有误差更不用说运算了(计算机使用的二进制不能完全精准的表示十进制);
BigDecimalDemo:
- /**
- * 2022年7月28日上午9:59:00
- */
- package testBigDecimal;
-
- import java.math.BigDecimal;
- import java.math.BigInteger;
- import java.math.MathContext;
- import java.math.RoundingMode;
- import java.util.Arrays;
-
- /**
- * @author XWF
- *
- */
- public class TestBigDecimal {
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- test1();
- test2();
- }
-
- public static void test1() {
- System.out.println("========== test1 ==========");
- System.out.println("BigInteger : " + new BigDecimal(BigInteger.TWO));
- System.out.println("char[] : " + new BigDecimal(new char[] {'1', '2', '.', '3', '4'}));
- System.out.println("double : " + new BigDecimal(1.2345d));//double类型精度有问题
- System.out.println("int : " + new BigDecimal(123));
- System.out.println("long : " + new BigDecimal(1234567890123456789L));
- System.out.println("string : " + new BigDecimal("1.2345"));//优先使用string
- System.out.println("BigInteger scale : " + new BigDecimal(BigInteger.valueOf(123456), 3));//unscaledVal x 10^(-scale)
- System.out.println("BigInteger scale : " + new BigDecimal(BigInteger.valueOf(123456), -2));
- System.out.println("char[] offset len : " + new BigDecimal(new char[] {'1', '2', '.', '3', '4'}, 1, 3));
-
- MathContext mc = new MathContext(3);//保留3位有效数字
- System.out.println("MathContext BigInteger : " + new BigDecimal(BigInteger.valueOf(54321), mc));
- System.out.println("MathContext char[] : " + new BigDecimal(new char[] {'1', '2', '.', '3', '4'}, mc));
- System.out.println("MathContext double : " + new BigDecimal(1.2345d, mc));
- System.out.println("MathContext int : " + new BigDecimal(123, mc));
- System.out.println("MathContext long : " + new BigDecimal(1234567890123456789L, mc));
- System.out.println("MathContext string : " + new BigDecimal("12345", mc));
- System.out.println("MathContext BigInteger scale : " + new BigDecimal(BigInteger.valueOf(123456), 3, mc));
- System.out.println("MathContext char[] offset len : " + new BigDecimal(new char[] {'1', '2', '.', '3', '4'}, 1, 3, mc));
- }
-
- public static void test2() {
- System.out.println("========== test2 ==========");
- BigDecimal bd1 = new BigDecimal("-9");
- BigDecimal bd2 = new BigDecimal("4");
- BigDecimal bd3 = new BigDecimal("12.3456");
- //大部分操作可以加MathContext参数进行设置
- System.out.println("绝对值 : " + bd1.abs());
- // bd1.abs(MathContext);
- System.out.println("+ : " + bd1.add(bd2));//-9+4
- System.out.println("- : " + bd1.subtract(bd2));//-9-4
- System.out.println("* : " + bd1.multiply(bd2));//-9*4
- System.out.println("/ : " + bd1.divide(bd2));//-9/4
- System.out.println("商 : " + bd1.divideToIntegralValue(bd2));//-9/4后取整
- System.out.println("商、余数 : " + Arrays.asList(bd1.divideAndRemainder(bd2)));//获得商和余数
- System.out.println("max : " + bd1.max(bd2));//返回较大值
- System.out.println("min : " + bd1.min(bd2));//返回较小值
- System.out.println("点左移 : " + bd2.movePointLeft(2));//小数点左移,x10^n
- System.out.println("点右移 : " + bd2.movePointRight(3));//小数点右移,x10^-n
- System.out.println("(-) : " + bd2.negate());//-this
- System.out.println("(+) : " + bd2.plus());//+this
- System.out.println("幂 : " + bd2.pow(3));//n次方
- System.out.println("有效位数 : " + bd3.precision());//返回有效数字位数
- System.out.println("取余 : " + bd1.remainder(bd2));//取余
- System.out.println("舍入 : " + bd3.round(new MathContext(4, RoundingMode.DOWN)));//设置四舍五入和有效位数
- System.out.println("scale : " + bd3.scale());//小数位数
- System.out.println("符号 : " + bd2.signum());//返回符号,返回-1表示负数,返回0表示0,返回1表示正数
- System.out.println("sqrt : " + bd2.sqrt(MathContext.DECIMAL64));//开方
- System.out.println("比较 : " + bd1.compareTo(bd2));//-1 <, 0 =, 1 >
- System.out.println("======转换======");
- System.out.println(bd3.doubleValue());
- System.out.println(bd3.floatValue());
- System.out.println(bd3.intValue());
- // System.out.println(bd3.intValueExact());//有非0小数或者超过int长度,抛出异常
- System.out.println(bd3.longValue());
- // System.out.println(bd3.longValueExact());//有非0小数或者超过long长度,抛出异常
- System.out.println(bd3.byteValue());
- // System.out.println(bd3.byteValueExact());//有非0小数或者超过byte长度,抛出异常
- System.out.println(bd3.shortValue());
- // System.out.println(bd3.shortValueExact());//有非0小数或者超过short长度,抛出异常
- }
-
- }
运行结果:
注:创建BigDecimal的时候最好使用String,直接使用float或者double会直接造成误差;
关于BigInteger,大部分运算跟BigDecimal一样,也有一些特有方法:
- /**
- * 2022年7月28日下午3:50:06
- */
- package testBigDecimal;
-
- import java.math.BigInteger;
- import java.util.Random;
-
- /**
- * @author XWF
- *
- */
- public class TestBigInteger {
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- Random rnd = new Random();
-
- System.out.println(BigInteger.ONE);
- System.out.println(BigInteger.TWO);
- System.out.println(BigInteger.ZERO);
- System.out.println(BigInteger.TEN);
- System.out.println(BigInteger.probablePrime(10, rnd));//10bit长的一个随机质数
- System.out.println(BigInteger.valueOf(1234567890L));
-
- System.out.println("====================");
- System.out.println(new BigInteger(new byte[] {48,57}));
- System.out.println(new BigInteger("111"));
- System.out.println(new BigInteger(-1, new byte[] {48, 57}));//带正负号的,-1负数,1正数,0只能用于0
- System.out.println(new BigInteger(3, rnd));//生成一个3bit的随机整数,0-7
- System.out.println(new BigInteger("12", 8));//8进制的12
- System.out.println(new BigInteger(new byte[] {1, 2, 3, 4}, 2, 2));//offset,len取byte数组,3=00000011,4=00000100,0000001100000100=772
- System.out.println(new BigInteger(6, 10, rnd));//随机6bit长的质数,容忍1-(1/2)^10的准确性
- System.out.println(new BigInteger(-1, new byte[] {1, 2, 3, 4}, 2, 2));//带正负号的
-
- System.out.println("====================");
- BigInteger bi1 = new BigInteger("2");
- BigInteger bi2 = new BigInteger("6");
- System.out.println(bi1.and(bi2));//bi1 & bi2
- System.out.println(bi1.andNot(bi2));//bi1 & ~bi2
- System.out.println(bi2.bitCount());//bit为1的个数
- System.out.println(bi2.bitLength());//bit长度
- System.out.println(bi2.clearBit(2));//bi2 & ~(1<
- System.out.println(bi2.flipBit(1));//bi2 ^ (1<
- System.out.println(bi2.gcd(bi1));//最大公约数
- System.out.println(bi2.or(bi1));//bi2 | bi1
- }
-
- }
运算结果:
关于MathContext,主要用于设置有效位数和设置四舍五入方式;
主要就是RoundingMode枚举里的几种舍入方式:
java文档里的例子:
Demo:
- /**
- * 2022年7月29日上午9:18:03
- */
- package testBigDecimal;
-
- import java.math.BigDecimal;
- import java.math.MathContext;
- import java.math.RoundingMode;
-
- /**
- * @author XWF
- *
- */
- public class TestMathContext {
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- MathContext mc = MathContext.UNLIMITED;//precision=0 roundingMode=HALF_UP
- mc = MathContext.DECIMAL32;//IEEE 754R, HALF_EVEN
- mc = MathContext.DECIMAL64;
- mc = MathContext.DECIMAL128;
-
- mc = new MathContext(4);//设置有效数字位数
- mc = new MathContext("precision=9 roundingMode=HALF_UP");//使用规定格式的字符串创建
- mc = new MathContext(4, RoundingMode.CEILING);//设置有效数字位数和四舍五入规则
- System.out.println(new BigDecimal("12.3456789", mc));
- mc = new MathContext(4, RoundingMode.DOWN);
- System.out.println(new BigDecimal("12.3456789", mc));
- }
-
- }