BigDecimal和BigInteger常用方法

这篇博客探讨了在Java中进行高精度计算的重要性,通过示例展示了double类型的精度问题,并对比了BigDecimal和BigInteger两个类在处理高精度计算时的优势。BigDecimal用于精确的浮点数运算,避免了二进制表示导致的误差;而BigInteger适用于大数据的整数运算,例如计算阶乘。文章通过测试用例详细展示了这两个类的使用方法。
package demo.api;

import org.junit.Test;

import java.math.BigDecimal;
import java.math.BigInteger;

public class BigDecimal和BigInteger {

    /**
     * double只适合科学计算法
     */
    @Test
    public void testDouble() {
        double d1 = 0.1;
        double d2 = 0.006;
        System.out.println(d1 + d2);//0.10600000000000001
        double d3 = 2.0;
        double d4 = 1.1;
        //二进制运算导致的误差, 二进制的1/10,十进制的1/3
        System.out.println(d3 - d4);//0.8999999999999999
    }

    /**
     * BigDecimal适合高精度计算
     */
    @Test
    public void testBigDecimal() {
        //两种赋值方法
        BigDecimal d1 = new BigDecimal("0.1");
        BigDecimal d2 = BigDecimal.valueOf(0.006);
        System.out.println("加:" + d1.add(d2));
        System.out.println("减:" + d1.subtract(d2));
        System.out.println("乘:" + d1.multiply(d2));
        //divide(商,几位小数,如何舍取    ROUND_HALF_UP向上取舍)
        System.out.println("除:" + d1.divide(d2, 10, BigDecimal.ROUND_HALF_UP));
        //原数不变(转换为double类型显示)
        System.out.println("d1: " + d1.doubleValue());
        System.out.println("d2: " + d2.doubleValue());
    }

    /**
     * BigInteger 大数据运算
     */
    @Test
    public void testBigInteger() {
        BigInteger b1 = new BigInteger("1");
        for (int i = 1; i <= 21; i++) {
            BigInteger bi = BigInteger.valueOf(i);
            b1 = b1.multiply(bi);
        }
        System.out.println("21的阶乘:" + b1);
    }
}

public class BigDecimal extends Number implements Comparable<BigDecimal> { /* * Let l = log_2(10). * Then, L < l < L + ulp(L) / 2, that is, L = roundTiesToEven(l). */ private static final double L = 3.321928094887362; private static final int P_F = Float.PRECISION; // 24 private static final int Q_MIN_F = Float.MIN_EXPONENT - (P_F - 1); // -149 private static final int Q_MAX_F = Float.MAX_EXPONENT - (P_F - 1); // 104 private static final int P_D = Double.PRECISION; // 53 private static final int Q_MIN_D = (Double.MIN_EXPONENT - (P_D - 1)); // -1_074 private static final int Q_MAX_D = (Double.MAX_EXPONENT - (P_D - 1)); // 971 /** * The unscaled value of this BigDecimal, as returned by {@link * #unscaledValue}. * * @serial * @see #unscaledValue */ private final BigInteger intVal; /** * The scale of this BigDecimal, as returned by {@link #scale}. * * @serial * @see #scale */ private final int scale; // Note: this may have any value, so // calculations must be done in longs /** * The number of decimal digits in this BigDecimal, or 0 if the * number of digits are not known (lookaside information). If * nonzero, the value is guaranteed correct. Use the precision() * method to obtain and set the value if it might be 0. This * field is mutable until set nonzero. * * @since 1.5 */ private transient int precision; /** * Used to store the canonical string representation, if computed. */ private transient String stringCache; /** * Sentinel value for {@link #intCompact} indicating the * significand information is only available from {@code intVal}. */ static final long INFLATED = Long.MIN_VALUE; private static final BigInteger INFLATED_BIGINT = BigInteger.valueOf(INFLATED); /** * If the absolute value of the significand of this BigDecimal is * less than or equal to {@code Long.MAX_VALUE}, the value can be * compactly stored in this field and used in computations. */ private final transient long intCompact; // All 18-digit base ten strings fit into a long; not all 19-digit // strings will private static final int MAX_COMPACT_DIGITS = 18; /* Appease the serialization gods */ @java.io.Serial private static final long serialVersionUID = 6108874887143696463L; // Cache of common small BigDecimal values. private static final BigDecimal[] ZERO_THROUGH_TEN = { new BigDecimal(BigInteger.ZERO, 0, 0, 1), new BigDecimal(BigInteger.ONE, 1, 0, 1), new BigDecimal(BigInteger.TWO, 2, 0, 1), new BigDecimal(BigInteger.valueOf(3), 3, 0, 1), new BigDecimal(BigInteger.valueOf(4), 4, 0, 1), new BigDecimal(BigInteger.valueOf(5), 5, 0, 1), new BigDecimal(BigInteger.valueOf(6), 6, 0, 1), new BigDecimal(BigInteger.valueOf(7), 7, 0, 1), new BigDecimal(BigInteger.valueOf(8), 8, 0, 1), new BigDecimal(BigInteger.valueOf(9), 9, 0, 1), new BigDecimal(BigInteger.TEN, 10, 0, 2), }; // Cache of zero scaled by 0 - 15 private static final BigDecimal[] ZERO_SCALED_BY = { ZERO_THROUGH_TEN[0], new BigDecimal(BigInteger.ZERO, 0, 1, 1), new BigDecimal(BigInteger.ZERO, 0, 2, 1), new BigDecimal(BigInteger.ZERO, 0, 3, 1), new BigDecimal(BigInteger.ZERO, 0, 4, 1), new BigDecimal(BigInteger.ZERO, 0, 5, 1), new BigDecimal(BigInteger.ZERO, 0, 6, 1), new BigDecimal(BigInteger.ZERO, 0, 7, 1), new BigDecimal(BigInteger.ZERO, 0, 8, 1), new BigDecimal(BigInteger.ZERO, 0, 9, 1), new BigDecimal(BigInteger.ZERO, 0, 10, 1), new BigDecimal(BigInteger.ZERO, 0, 11, 1), new BigDecimal(BigInteger.ZERO, 0, 12, 1), new BigDecimal(BigInteger.ZERO, 0, 13, 1), new BigDecimal(BigInteger.ZERO, 0, 14, 1), new BigDecimal(BigInteger.ZERO, 0, 15, 1), }; // Half of Long.MIN_VALUE & Long.MAX_VALUE. private static final long HALF_LONG_MAX_VALUE = Long.MAX_VALUE / 2; private static final long HALF_LONG_MIN_VALUE = Long.MIN_VALUE / 2; // Constants
最新发布
10-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值