一、IEEE754 标准浮点格式
- 格式:数符 + 阶码 + 尾数
①. 32 位(单精度浮点数): 1 + 8 + 23
数符是尾数的符号位;
阶码移码表示,但偏置量为 127,不是 128(2^7);
尾数用原码表示;
隐含约定尾数最高位 20 ,即 1。
②. 64 位(双精度浮点数):1 + 11 + 52
二、IEEE754 的四种舍入方式
-
最近舍入(Round to Nearest)(默认的舍入方式,也称为向偶舍入,java 浮点数的舍入方式)
Round(0.5) = 0; Round(1.5) = 2; Round(2.5) = 2; -
向 0 舍入
(int) 1.3 = 1,(int) -1.3 = -1; -
向下舍入
floor(1.3) = 1,floor(-1.3) = -2 -
向上舍入
ceil(1.3) = 2。Ceil(-1.3) = -1;
三、为什么浮点计算不准确
2 进制的小数无法精确的表达某些 10 进制小数。
四、BigDecimal
BigDecimal 可以表示任意精度的小数,并对它们进行计算。
由于 BigDecimal 对象是不可变的,加、减、乘、除中的每一个都会产生新的 BigDecimal 对象。
- 构造方法
bigDecimal = new BigDecimal(new char[]{'1','2'});//char[]
bigDecimal = new BigDecimal(1.2);//double
bigDecimal = new BigDecimal(5);//int
bigDecimal = new BigDecimal(5L);//long
bigDecimal = new BigDecimal("1.2");//String
- 加减乘除运算
BigDecimal a = new BigDecimal("5.5");
BigDecimal b = new BigDecimal("1.2");
BigDecimal c = null;
c = a.add(b); //c = a + b
c = a.subtract(b); //c = a - b
c = a.multiply(b); //c = a * b
c = a.divide(b); //c = a / b
- 小数舍入
setScale(newScale, roundingMode) // 设置设置小数位数及取舍方式,newScale为小数位数
roundingMode 有如下几种:
BigDecimal.ROUND_CEILING; // 向正无穷方向取整
BigDecimal.ROUND_DOWN; // 向0方向取整
BigDecimal.ROUND_FLOOR; // 向负无穷方向取整
BigDecimal.ROUND_HALF_DOWN; // 小数>0.5向非0方向进位,其他向0方向进位
BigDecimal.ROUND_HALF_EVEN; // 小数偶数同ROUND_HALF_DOWN,奇数同ROUND_HALF_UP
BigDecimal.ROUND_HALF_UP; // 小数>=0.5向非0方向进位,其他向0方向进位
BigDecimal.ROUND_UNNECESSARY;//断言所请求的操作具有精确的结果,因此不需要舍入。 如果在产生不精确结果的操作上指定此舍入模式,则抛出ArithmeticException
BigDecimal.ROUND_UP; //向非0方向取整
- 补充
首选 String 类型的构造函数(double 类型的误差导致 BigDecimal 接收到的值会有误差)
除法操作需要设置小数位数(因为如果结果出现无限小数,会抛出异常)
不要使用 equals 判断是否相等(比较两个 BigDecimal 数值是否相等,应使用 compareTo() 方法而不是 equals()方法。)
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于