当所需要的计算的数字特别大的时候,超出了数据类型的范围,如果还想要计算话就需要用到大数类,但是虽然大数类支持大数的计算,但是如果遇到算两个大数的乘方,还是需要很长时间的计算,因此尽可能要少使用。但是如果在用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类的数组,第一元存储的是商数,第二元存储的是余数。