A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 王琪 中级黑马   /  2014-3-1 18:15  /  1017 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

浮点数输出(科学记数法)
        Java浮点型数值在大于9999999.0就自动转化为科学记数法来表示:
            System.out.println(999999999.04);
            System.out.println(99999999.04);
            System.out.println(10000000.01);
            System.out.println(9999999.04);
        输出的结果如下:
        9.9999999904E8
        9.999999904E7
        1.000000001E7
        9999999.04
     但有时我们可能不需要科学记数法的表示方法,需要转换为字符串,还不能直接用toString()等方法转换,很烦琐。
BigDecimal介绍BigDecimal是Java提供的一个不变的、任意精度的有符号十进制数对象。它提供了四个构造器,
有两个是用BigInteger构造,在这里我们不关心,我们重点看用double和String构造的两个构造器(有关BigInteger详细介绍请查阅j2se API文档)。
        BigDecimal(double val)
                  Translates a double into a BigDecimal. BigDecimal(String val)
                  Translates the String representation of a BigDecimal into a BigDecimal.
       BigDecimal(double)是把一个double类型十进制数构造为一个BigDecimal对象实例。
        BigDecimal(String)是把一个以String表示的BigDecimal对象构造为BigDecimal对象实例。
        习惯上,对于浮点数我们都会定义为double或float,
        注意:这个构造器的结果可能会有不可预知的结果。有人可能设想new BigDecimal(.1)等于.1是正确的。
        但它实际上是等于.1000000000000000055511151231257827021181583404541015625。
        这就是为什么.1不能用一个double精确表示的原因,因此,这个被放进构造器中的长值并不精确的等于.1,尽管外观看起来是相等的。
        然而(String)构造器,则完全可预知的,new BigDecimal(“.1”)如同期望的那样精确的等于.1,因此,(String)构造器是被优先推荐使用的。
        看下面的结果:
              System.out.println(new BigDecimal(123456789.02).toString());
              System.out.println(new BigDecimal("123456789.02").toString());
        输出为:
        123456789.01999999582767486572265625
        123456789.02

        现在我们知道,如果需要精确计算,非要用String来够造BigDecimal不可!
        实现方案现在我们已经知道怎么解决这个问题了,原则上是使用BigDecimal(String)构造器。
我们建议,在商业应用开发中,涉及金额等浮点数计算的数据,全部定义为String,数据库中可定义为字符型字段,在需要使用这些数据进行运算的时候。
使用BigDecimal(String)构造BigDecimal对象进行运算,保证数据的精确计算。同时避免了科学记数法的出现。如果科学记数表示法在应用中不是一种负担的话,可以考虑定义为浮点类型。

        这里我们提供了一个工具类,定义浮点数的加、减、乘、除和四舍五入等运算方法。以供参考。
        源文件MathExtend.java:
        import java.math.BigDecimal;
        public class MathExtend
        {
          //默认除法运算精度
          private static final int DEFAULT_DIV_SCALE = 10;
         /**
          * 提供精确的加法运算。
          * @param v1
          * @param v2
          * @return 两个参数的和
          */
          public static double 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 static String add(String v1, String v2)
          {
              BigDecimal b1 = new BigDecimal(v1);
              BigDecimal b2 = new BigDecimal(v2);
              return b1.add(b2).toString();
          }
         /**
          * 提供精确的减法运算。
          * @param v1
          * @param v2
          * @return 两个参数的差
          */
          public static double subtract(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 static String subtract(String v1, String v2)
          {
              BigDecimal b1 = new BigDecimal(v1);
              BigDecimal b2 = new BigDecimal(v2);
              return b1.subtract(b2).toString();
          }
          /**
          * 提供精确的乘法运算。
          * @param v1
          * @param v2
          * @return 两个参数的积
          */
          public static double multiply(double v1, double v2)
          {
              BigDecimal b1 = new BigDecimal(Double.toString(v1));
              BigDecimal b2 = new BigDecimal(Double.toString(v2));
              return b1.multiply(b2).doubleValue();
          }
         
          /**
           * 提供精确的乘法运算
           * @param v1
           * @param v2
           * @return 两个参数的数学积,以字符串格式返回
           */
          public static String multiply(String v1, String v2)
          {
              BigDecimal b1 = new BigDecimal(v1);
              BigDecimal b2 = new BigDecimal(v2);
              return b1.multiply(b2).toString();
          }
         /**
          * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
          * 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
          * @param v1
          * @param v2
          * @return 两个参数的商
          */
          public static double divide(double v1, double v2)
          {
              return divide(v1, v2, DEFAULT_DIV_SCALE);
          }
         
          /**
           * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
           * 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN
           * @param v1
           * @param v2
           * @param scale 表示需要精确到小数点以后几位。
           * @return 两个参数的商
           */
          public static double divide(double v1,double v2, int scale)
          {
              return divide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);
          }
         
          /**
           * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
           * 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式
           * @param v1
           * @param v2
           * @param scale 表示需要精确到小数点以后几位
           * @param round_mode 表示用户指定的舍入模式
           * @return 两个参数的商
           */
          public static double divide(double v1,double v2,int scale, int round_mode){
                  if(scale < 0)
                  {
                      throw new IllegalArgumentException("The scale must be a positive integer or zero");
                  }
                  BigDecimal b1 = new BigDecimal(Double.toString(v1));
                  BigDecimal b2 = new BigDecimal(Double.toString(v2));
                  return b1.divide(b2, scale, round_mode).doubleValue();
          }
          /**
           * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
           * 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
           * @param v1
           * @param v2
           * @return 两个参数的商,以字符串格式返回
           */
          public static String divide(String v1, String v2)
          {
              return divide(v1, v2, DEFAULT_DIV_SCALE);
          }

         

      

评分

参与人数 1黑马币 +5 收起 理由
何伟超 + 5

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马