摘要:本文学习了如何使用大数值处理大整数和高精度浮点数。
环境
Windows 10 企业版 LTSC 21H2
Java 1.8
1 BigInteger
在整数类型里面,byte为8位,short为16位,int为32位,long为64位,这些数值的二进制位数已经固定,能表示的数值大小就有一定的范围限制,因此提供BigInteger类来处理更大的数字。
构造方法:
java1 2
| public BigInteger(String val)
|
常用方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public BigInteger add(BigInteger val)
public BigInteger subtract(BigInteger val)
public BigInteger multiply(BigInteger val)
public BigInteger divide(BigInteger val)
public BigInteger[] divideAndRemainder(BigInteger val)
public String toString()
public double doubleValue()
public float floatValue()
public long longValue()
public int intValue()
|
示例:
java1 2 3 4 5 6 7 8 9 10
| public void test() { BigInteger a = new BigInteger("10"); BigInteger b = new BigInteger("3"); System.out.println("add >>> " + a.add(b)); System.out.println("subtract >>> " + a.subtract(b)); System.out.println("multiply >>> " + a.multiply(b)); System.out.println("divide >>> " + a.divide(b)); System.out.println("divideAndRemainder[0] >>> " + a.divideAndRemainder[b](0)); System.out.println("divideAndRemainder[1] >>> " + a.divideAndRemainder[b](1)); }
|
2 BigDecimal
在使用float和double的时候,可能会出现精度缺失的问题:
java1 2 3 4 5 6
| public void test() { System.out.println(0.2 + 0.1); System.out.println(0.3 - 0.1); System.out.println(0.2 * 0.1); System.out.println(0.3 / 0.1); }
|
虽然基本类型提供了float和double类型,但在执行浮点运算的时候,只是提供了一个较为精确的结果,不能用于要求精确度很高的环境中,因此提供了BigDecimal类来保证结果的精确度。
在进行每一步运算时,都会产生一个新的对象,所以在使用BigDecimal做运算时要保存操作后的值。
使用BigDecimal的坏处是性能比double和float差,在处理庞大复杂的运算时尤为明显,因根据实际需求决定使用哪种类型。
构造方法:
java1 2 3 4 5 6
| public BigDecimal(int val)
public BigDecimal(double val)
public BigDecimal(String val)
|
因为float和double会导致精度缺失的问题,所以不建议使用将double作为参数的构造方法:
java1 2 3 4 5 6 7 8
| public void test() { BigDecimal a = new BigDecimal(2); BigDecimal b = new BigDecimal(2.3); BigDecimal c = new BigDecimal("2.3"); System.out.println(a); System.out.println(b); System.out.println(c); }
|
常用方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public BigDecimal add(BigDecimal augend)
public BigDecimal subtract(BigDecimal subtrahend)
public BigDecimal multiply(BigDecimal multiplicand)
public BigDecimal divide(BigDecimal divisor)
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
public BigDecimal[] divideAndRemainder(BigDecimal divisor)
public BigDecimal setScale(int newScale, int roundingMode)
public String toString()
public double doubleValue()
public float floatValue()
public int intValue()
|
舍入模式:
- ROUND_UP:向远离零的方向舍入。舍弃非零部分,并将非零舍弃部分相邻的一位数字加一。
- ROUND_DOWN:向接近零的方向舍入。舍弃非零部分,同时不会非零舍弃部分相邻的一位数字加一,采取截取行为。
- ROUND_CEILING:向正无穷的方向舍入。如果为正数,舍入结果同ROUND_UP一致;如果为负数,舍入结果同ROUND_DOWN一致。
- ROUND_FLOOR:向负无穷的方向舍入。如果为正数,舍入结果同ROUND_DOWN一致;如果为负数,舍入结果同ROUND_UP一致。
- ROUND_HALF_UP:向最接近的数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式,即四舍五入。
- ROUND_HALF_DOWN:向最接近的数字舍入,如果与两个相邻数字的距离相等,则为向下舍入的舍入模式,即五舍六入。
- ROUND_UNNECESSARY:断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。
示例:
java1 2 3 4 5 6 7 8 9 10 11
| public void test() { BigDecimal a = new BigDecimal(10); BigDecimal b = new BigDecimal(3); System.out.println("add >>> " + a.add(b)); System.out.println("subtract >>> " + a.subtract(b)); System.out.println("multiply >>> " + a.multiply(b)); System.out.println("divide >>> " + a.divide(b, 2, BigDecimal.ROUND_HALF_UP)); System.out.println("divideAndRemainder[0] >>> " + a.divideAndRemainder[b](0)); System.out.println("divideAndRemainder[1] >>> " + a.divideAndRemainder[b](1)); }
|
条