JavaDemo——关于BigDecimal类

x33g5p2x  于2022-08-17 转载在 Java  
字(7.1k)|赞(0)|评价(0)|浏览(409)

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<<n)
		System.out.println(bi2.flipBit(1));//bi2 ^ (1<<n)
		System.out.println(bi2.gcd(bi1));//最大公约数
		System.out.println(bi2.or(bi1));//bi2 | bi1
	}

}

运算结果:

关于MathContext,主要用于设置有效位数和设置四舍五入方式;

主要就是RoundingMode枚举里的几种舍入方式:

  • DOWN:朝向0舍入,直观就是去掉舍入位;
  • UP:远离0舍入,去掉舍入位,正数向正方向进1,负数向负方向进1;(舍入位非0才进位,下同)
  • CEILING:朝向正无穷舍入,正数使用UP,负数使用DOWN;
  • FLOOR:朝向负无穷舍入,正数使用DOWN,负数使用UP;
  • HALF_DOWN:五舍六入,舍入>0.5使用UP,否则使用DOWN;
  • HALF_UP:四舍五入,舍入>=0.5使用UP,否则使用DOWN;
  • HALF_EVEN:四舍六入,舍入位=0.5需要分情况,如果舍入位左边是奇数则用HALF_UP(UP),是偶数则用HALF_DOWN(DOWN);
  • UNNECESSARY:不需要舍入,如果给定值不是精确值则抛出ArithmeticException异常;

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

}

相关文章