大数类

扫码查看

当所需要的计算的数字特别大的时候,超出了数据类型的范围,如果还想要计算话就需要用到大数类,但是虽然大数类支持大数的计算,但是如果遇到算两个大数的乘方,还是需要很长时间的计算,因此尽可能要少使用。但是如果在用double或者float类型的时候出现了,精度不准的情况,还需要用大数类,代码如下:

package Test;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
public class Test {
    public static double round1(double num,int scale) {
        return new BigDecimal(num).divide(new BigDecimal(1.0),scale,RoundingMode.HALF_UP).doubleValue();
        /*
         *     向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
            如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。
         *
         */
    }
    public static double round2(double num,int scale) {
        return new BigDecimal(num).divide(new BigDecimal(1.0),scale,RoundingMode.HALF_DOWN).doubleValue();
        /*
              向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
            如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。

         */
    }
    public static double round3(double num,int scale) {
        return new BigDecimal(num).divide(new BigDecimal(1.0),scale,RoundingMode.HALF_EVEN).doubleValue();
        /*
             向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
            如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;
            如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。
            注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
            此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
            如果前一位为奇数,则入位,否则舍去。
            以下例子为保留小数点1位,那么这种舍入方式下的结果
         */
    }
public static void main(String[] args) {
    BigInteger bigA = new BigInteger("54688798756446");
    BigInteger bigB = new BigInteger("156488");
    double b =0.99;
    BigDecimal f1 = new BigDecimal("0.05");
    BigDecimal f2 = BigDecimal.valueOf(0.01);
    BigDecimal f3 = new BigDecimal(0.05);
    BigInteger result[] = bigA.divideAndRemainder(bigB);
    System.out.println("_1_    大数加法: "+bigA.add(bigB));
    System.out.println("_2_    大数减法: "+bigA.subtract(bigB));
    System.out.println("_3_    大数乘法: "+bigA.multiply(bigB));
    System.out.println("_4_    大数除法: "+bigA.divide(bigB));
    System.out.println("_5_    "+new BigDecimal(0.99));
    System.out.println("_6_    "+new BigDecimal(0.99).toString());
    System.out.println("_7_    "+new BigDecimal("0.99").toString());
    System.out.println("_8_    "+new BigDecimal("0.99"));
    System.out.println("_9_    "+BigDecimal.valueOf(0.99));
    System.out.println("_10_    "+BigDecimal.valueOf(0.99f));
    System.out.println("_11_    "+"商数  "+result[0]+"余数  "+result[1]);
    System.out.println("_12_    进位"+Test.round1(19.6352,2));
    System.out.println("_13_    进位"+Test.round2(19.6332,2));
    System.out.println("_14_    进位"+Test.round3(19.6252,2));
    System.out.println("_15_    "+b*1);
    System.out.println("_16_    0.05 + 0.01 = " + f1.add(f2));
    System.out.println("_17_    0.05 - 0.01 = " + f1.subtract(f2));
    System.out.println("_18_    0.05 * 0.01 = " + f1.multiply(f2));
    System.out.println("_19_    0.05 / 0.01 = " + f1.divide(f2));
    System.out.println("_20_    0.05 + 0.01 = " + f3.add(f2));
    System.out.println("_21_    0.05 - 0.01 = " + f3.subtract(f2));
    System.out.println("_22_      0.05 * 0.01 = " + f3.multiply(f2));
    System.out.println("_23_      0.05 / 0.01 = " + f3.divide(f2));
    System.out.println("_24_      "+f3);
}
}

运行结果如下:

可见在编号24中,新建的BigDecimal对象中写的是0.05,但是输出的不是准确的0.05,而是后面还有很多的小数,而用大数类参数为double类型的方法也不能进行精准的计算,只有调用BigDecimal的valueof( double value)方法和BigDecimal(Stringvalue)的构造方法才能进行精确的计算,实际上,在进行存储的时候,对0.05进行了精度拓展,所以在当遇到需要涉及到精确计算的时候,如上面代码所示,要注意该构造函数是一个精确的转换,它无法得到与先调用Double.toString(double)方法将double转换成String,再使用BigDecimal(String)构造函数一样的结果。如果要达到这种结果,应该使用new BigDecimal(Stringvalue){在括号里面写入字符串数字} 或 BigDecimal.valueof( double value){直接写数字},还有关于进位的方法也有很多,规则也不尽相同,其中BigInteger类有个方法divideAndRemainder()用来计算,商数和余数,其返回的是BigInteger类的数组,第一元存储的是商数,第二元存储的是余数。

01-31 19:54
查看更多