java-java.math.BigDecimal

来源:互联网 发布:手机五线谱编辑软件 编辑:程序博客网 时间:2024/05/18 13:06

如果在java中使用浮点数,则默认为double。如果需要使用float,在浮点数后面加f。

Java代码 复制代码 收藏代码
  1. public class Test { 
  2.  
  3.     public staticvoid main(String[] args) { 
  4.         System.out.print("直接输出2.4:"); 
  5.         System.out.println(2.4); 
  6.         System.out.print("2.4/0.1:"); 
  7.         System.out.println(2.4/0.1); 
  8.         System.out.print("(2.4-0.2)/0.1:"); 
  9.         System.out.println((2.4-0.2)/0.1); 
  10.         System.out.print("直接输出2.2:"); 
  11.         System.out.println(2.2); 
  12.         System.out.print("2.2/0.1:"); 
  13.         System.out.println(2.2/0.1); 
  14.         System.out.print("(2.2+0.2)/0.1:"); 
  15.         System.out.println((2.2+0.2)/0.1); 
  16.         System.out.print("2.2+0.2:"); 
  17.         System.out.println(2.2+0.2); 
  18.     } 


输出结果:

Html代码 复制代码 收藏代码
  1. 直接输出2.4:2.4 
  2. 2.4/0.1:23.999999999999996 
  3. (2.4-0.2)/0.1:21.999999999999996 
  4. 直接输出2.2:2.2 
  5. 2.2/0.1:22.0 
  6. (2.2+0.2)/0.1:24.000000000000004 
  7. 2.2+0.2:2.4000000000000004 



        我们从源代码和输出的结果进行分析。首先从结果可以知道直接输出浮点数2.2和2.4没有问题,一切正常。但是2.4/0.1我们期望应该是输出24,却输出了23.999999999999996;同样的,(2.4-0.2)/0.1期望输出是22,实际输出是21.999999999999996,(2.2+0.2)/0.1也是同样的情况。这些现象说明我们得到了非期望值,一个“错误的结果”,也就是说,在计算过程中发生了精度丢失。
        前面说过,我在python中也有这样的问题,所以这种现象并不针对某种语言,而是计算机的实现造成的。众所周知,计算机只能识别二进制,所以我们的一切数据最后都转化为二进制来实现。我们发现,直接输出2.4和2.2并没有任何问题,但是一旦让其参与运算就会出错,因此精度丢失是发生在”运算“过程中的。
        浮点数由两部分组成,指数和尾数。如果在转换过程中进行了运算,那么所得结果将不可知,不能保证二进制能正好准确转换为十进制。其原理参见其他参考书。
        如何处理这种情况呢,可以用BigDecimal

一:

String myMoney = "100.0128";

    BigDecimal money= new BigDecimal(myMoney);

    //设置精度,以及舍入规则
    money= money.setScale(2, BigDecimal.ROUND_HALF_UP);

    System.out.println(money);

    //100.01

二:

     double myMoney = 100.0128;

     myMoney    = Math.round(myMoney    * 100) / (double) 100    ;

        BigDecimal money= new BigDecimal(myMoney);

        System.out.println(money); //后面则有很多的小数

     //为了保证小数位数为2位

     BigDecimal money= new BigDecimal(Double.toString(myMoney));

        System.out.println(money); //小数位数则为2位

三:
这个类确实好用。在网上找到大的,是一个女Java程序员写的。厉害~~~~~~哈哈
/*
* 创建日期 2004-10-14
*
* 如果需要精确计算,非要用String来够造BigDecimal不可
*/

package com.lims.actions.testqc.comm;

/**
* @author Jstar
*
*
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/

import java.math.BigDecimal;

/**
* 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精
* 确的浮点数运算,包括加减乘除和四舍五入。
*/


public class Arith {

   //默认除法运算精度
   private staticfinal int DEF_DIV_SCALE = 10;
   //这个类不能实例化

   private Arith() {}

  
/**
    * 提供精确的加法运算。
    * @param v1 被加数
    * @param v2 加数
    * @return 两个参数的和
    */


   public staticdouble add(double v1,double v2) {

      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.add(b2).doubleValue();
   }

  
/**
      * 提供精确的减法运算。
      * @param v1 被减数
      * @param v2 减数
      * @return 两个参数的差
      */


   public staticdouble sub(double v1,double v2) {

      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.subtract(b2).doubleValue();
   }

  
/**
      * 提供精确的乘法运算。
      * @param v1 被乘数
      * @param v2 乘数
      * @return 两个参数的积
      */


   public staticdouble mul(double v1,double v2) {

      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.multiply(b2).doubleValue();
   }

  
/**
      * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
      * 小数点以后10位,以后的数字四舍五入。
      * @param v1 被除数
      * @param v2 除数
      * @return 两个参数的商
      */


   public staticdouble div(double v1,double v2) {
      return div(v1, v2, DEF_DIV_SCALE);
   }

  
/**
      * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
      * 定精度,以后的数字四舍五入。
      * @param v1 被除数
      * @param v2 除数
      * @param scale 表示表示需要精确到小数点以后几位。
      * @return 两个参数的商
      */


   public staticdouble div(double v1,double v2, int scale) {

      if (scale < 0) {

    throw new IllegalArgumentException("The scale must be a positive integer or zero");
      }

      BigDecimal b = new BigDecimal(Double.toString(v));
      BigDecimal one = new BigDecimal("1");
      return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();


}
原创粉丝点击