关注·
点击蓝字,关注我吧
“ 我们知道Java中关于数值类型基本数据类型有int、float、double,双精度浮点型double可以处理16位有效数,int类型的数据可表示的数值范围为-231-231-1这个范围内的所有整数,但是整数的范围却远比前面提到的范围要大的多,这个时候就需要使用BigInteger来表示超出int类型范围的整数;双精度浮点型double可以处理16位有效小数,float和double只能用来做科学计算或者工程计算,如果要对超出16位的小数进行处理的话,在商业计算中就需要使用BigDecimal”
一、简介
1、什么时候要用到BigInteger?Java基本数据类型中的int固定为4个字节,int数据类型代表的是整数,但是int类型无法表示所有整数,也即当超出int类型所表示的范围的时候,会无法正确表示。来我们一起看一个例子就知道了,代码程序如下:
public static void main(String[] args) {// int类型可正确表示的最大值/最小值可以通过其包装类Integer获取int a = Integer.MAX_VALUE; System.out.println("int类型所能正确表示的最大值为:" + Integer.MAX_VALUE); System.out.println("int类型所能正确表示的最小值为:" + Integer.MIN_VALUE);// 如果我们给最大值加1的话,结果会是怎样呢? System.out.println("对int类型的最大值进行加1结果为:" + (Integer.MAX_VALUE+1)); }
程序的运行结果如下:
我们发现对int所能表示的最大正整数进行加1后居然编变成了最小的负整数,如果一个人在银行存了2147483647元钱,当他在存入1元钱的时候,他就“欠”银行2147483648元钱了,土豪自己知道了怕是要吐血而死啊!(至于为什么2147483647加1后会变成-2147483648,可以自己讲十进制数转换为二进制数在进行计算就可以啦,最高的一位为符号位)
2、什么时候要用到BigDecimal?
计算机采用二进制存储,使用double等会损失精度,精度损失,在处理非常大的数字或非常小的数字时非常明显。在许多情况下,带小数的十进制数字的二进制表示形式是近似值,而不是绝对值。其实说到底还是在计算机中用0、1二进制无法正确表示一些十进制数。所以当我们不能够容忍精度损失的时候,就需要使用BigDecimal。
一般来说,BigInteger用的不是很多,BigDecimal用的稍微多一点,BigDecimal的实现利用到了BigInteger, 所不同的是BigDecimal加入了小数位的概念,比如BigDecimal d = new BigDecimal(new BigInteger(ib),5);5表示的是5个小数位。BigDecimal可以用来做超大的浮点数的运算,比如+-*/的运算,其中除法运算是最复杂的,因为商的位数还有除不断的情况下末位小数点的处理都是需要考虑的。
二、BigDecimal的基本构造方法
public BigDecimal(char[] in)
public BigDecimal(String val)
public BigDecimal(double val) //这个需要注意
public BigDecimal(BigInteger val)
public BigDecimal(int val)
public BigDecimal(long val)
三、BigDecimal的算术运算
无法对BigDecimal进行传统的"+、-、*、/"运算,只能通过调用方法的方式进行运算。同时除法还应该指定保留的小数位数。
public static void main(String[] args) { BigDecimal number1 = new BigDecimal("333"); BigDecimal number2 = new BigDecimal("3"); System.out.println("加法:"+number1.add(number2)); System.out.println("减法:"+number1.subtract(number2)); System.out.println("乘法:"+number1.multiply(number2)); System.out.println("除法:"+number1.divide(number2)); }
程序运行结果如下:
四、特殊说明
关于BigDecimal的BigDecimal(double val) 构造方法,如果使用double类型的构造器,BigDecimal可能会得到一个不明确的数值。
public static void main(String[] args) { BigDecimal number1 = new BigDecimal(3.33); BigDecimal number2 = new BigDecimal(2); BigDecimal number3 = new BigDecimal("3.33"); System.out.println(number1.add(number2)); System.out.println(number1); System.out.println(number2); System.out.println(number3); }
程序运行如下:
可以看到3.33后面的都是不可以预料的且对其进行运算的时候,结果也是不可预料的和预期的。原因:
1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于
0.1000000000000000055511151231257827021181583404541015625。
这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal(“0.1”) 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法 。
当double必须用作BigDecimal的源时,请使用Double.toString(double)转成String,然后使用String构造方法,或使用BigDecimal的静态方法valueOf。
四、对BigDecimal小数进行处理 对以上代码进行一下改造,对结果进行小数位保留,可以通过 setScale()方法, 同时BigDecimal还提供了多种保留小数位的方法,如四舍五入方法BigDecimal.ROUND_HALF_UP以及进1法BigDecimal.ROUND_UP;
public static void main(String[] args) { // Java中3.33没有显示声明数据类型,默认为double BigDecimal number1 = new BigDecimal(3.33); BigDecimal number2 = new BigDecimal(2); BigDecimal number3 = new BigDecimal("3.33"); // 对和的结果保留两位小数,使用四舍五入 System.out.println(number1.add(number2).setScale(2,BigDecimal.ROUND_HALF_UP)); // 对number保留三位小时,使用进1法 System.out.println(number1.setScale(3,BigDecimal.ROUND_UP)); System.out.println(number2); System.out.println(number3); }
程序运行结果如下:
是新朋友吗?记得先点蓝字关注我哦~
客官都看到这里了,别忘了点亮您的赞哦
您的建议是我们成长的动力