网站开发设计jw100,网站通过微信支付宝收钱怎么做,长春 万网 网站建设,编程课有必要学吗1.引言 float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算#xff0c;这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而#xff0c;它们没有提供完全精确的结果#xff0c;所以不应该被用于要求精确结果的场合。但是…1.引言 float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而它们没有提供完全精确的结果所以不应该被用于要求精确结果的场合。但是商业计算往往要求结果精确这时候BigDecimal就派上大用场啦。 先看下面代码 public static void main(String[] args){System.out.println(0.2 0.1);System.out.println(0.3 - 0.1);System.out.println(0.2 * 0.1);System.out.println(0.3 / 0.1);} 运行结果如下 你认为你看错了但结果却是是这样的。问题在哪里呢原因在于我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。我们的CPU表示浮点数由两个部分组成指数和尾数这样的表示方法一般都会失去一定的精确度有些浮点数运算也会产生一定的误差。如2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。浮点数的值实际上是由一个特定的数学公式计算得到的。 其实java的float只能用来进行科学计算或工程计算在大多数的商业计算中一般采用java.math.BigDecimal类来进行精确计算。 2.BigDecimal构造方法 1.public BigDecimal(double val) 将double表示形式转换为BigDecimal *不建议使用 2.public BigDecimal(int val) 将int表示形式转换成BigDecimal 3.public BigDecimal(String val) 将String表示形式转换成BigDecimal 为什么不建议采用第一种构造方法呢来看例子 public static void main(String[] args){BigDecimal bigDecimal new BigDecimal(2);BigDecimal bDouble new BigDecimal(2.3);BigDecimal bString new BigDecimal(2.3);System.out.println(bigDecimal bigDecimal);System.out.println(bDouble bDouble);System.out.println(bString bString);} 运行结果如下 为什么会出现这种情况呢 JDK的描述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如下 public static void main(String[] args){BigDecimal bDouble1 BigDecimal.valueOf(2.3);BigDecimal bDouble2 new BigDecimal(Double.toString(2.3));System.out.println(bDouble1 bDouble1);System.out.println(bDouble2 bDouble2);} 结果如下 3.BigDecimal加减乘除运算 对于常用的加减乘除BigDecimal类提供了相应的成员方法。 public BigDecimal add(BigDecimal value); //加法public BigDecimal subtract(BigDecimal value); //减法 public BigDecimal multiply(BigDecimal value); //乘法public BigDecimal divide(BigDecimal value); //除法 大概的用法如下 public static void main(String[] args){BigDecimal a new BigDecimal(4.5);BigDecimal b new BigDecimal(1.5);System.out.println(a b a.add(b));System.out.println(a - b a.subtract(b));System.out.println(a * b a.multiply(b));System.out.println(a / b a.divide(b));} 运行结果 这里有一点需要注意的是除法运算divide. BigDecimal除法可能出现不能整除的情况比如 4.5/1.3这时会报错java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. 其实divide方法有可以传三个参数 public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 第一参数表示除数 第二个参数表示小数点后保留位数第三个参数表示舍入模式只有在作除法运算或四舍五入时才用到舍入模式有下面这几种 ROUND_CEILING //向正无穷方向舍入ROUND_DOWN //向零方向舍入ROUND_FLOOR //向负无穷方向舍入ROUND_HALF_DOWN //向距离最近的一边舍入除非两边的距离是相等,如果是这样向下舍入, 例如1.55 保留一位小数结果为1.5ROUND_HALF_EVEN //向距离最近的一边舍入除非两边的距离是相等,如果是这样如果保留位数是奇数使用ROUND_HALF_UP如果是偶数使用ROUND_HALF_DOWNROUND_HALF_UP //向距离最近的一边舍入除非两边的距离是相等,如果是这样向上舍入, 1.55保留一位小数结果为1.6ROUND_UNNECESSARY //计算结果是精确的不需要舍入模式ROUND_UP //向远离0的方向舍入 按照各自的需要可传入合适的第三个参数。四舍五入采用 ROUND_HALF_UP 需要对BigDecimal进行截断和四舍五入可用setScale方法例 public static void main(String[] args){BigDecimal a new BigDecimal(4.5635);a a.setScale(3, RoundingMode.HALF_UP); //保留3位小数且四舍五入System.out.println(a);} *减乘除其实最终都返回的是一个新的BigDecimal对象因为BigInteger与BigDecimal都是不可变的immutable的在进行每一步运算时都会产生一个新的对象 public static void main(String[] args){BigDecimal a new BigDecimal(4.5);BigDecimal b new BigDecimal(1.5);a.add(b);System.out.println(a); //输出4.5. 加减乘除方法会返回一个新的BigDecimal对象原来的a不变
} 4.总结 (1)商业计算使用BigDecimal。 (2)尽量使用参数类型为String的构造函数。 (3) BigDecimal都是不可变的immutable的在进行每一步运算时都会产生一个新的对象所以在做加减乘除运算时千万要保存操作后的值。 (4)我们往往容易忽略JDK底层的一些实现细节导致出现错误需要多加注意。 本文版权归作者和博客园共有欢迎转载但未经作者同意必须保留此段声明且在文章页面明显位置给出原文连接否则保留追究法律责任的权利。转载于:https://www.cnblogs.com/LeoBoy/p/6056394.html