java

          tiger

          常用鏈接

          統計

          my Blogs

          最新評論

          java取四舍五入的方法

          “帶下劃線內容無效"

          兩種不同方法的實現:


          1:
          /**

          * 提供小數位四舍五入處理。

          * @param v 需要四舍五入的數字

          * @param scale 小數點后保留幾位

          * @return 四舍五入后的結果

          */

          public static double round(double v,int scale){
          String temp="#,##0.";
          for (int i=0;i<scale ;i++ )
          {
          temp+="0";
          }
          return Double.valueOf(new java.text.DecimalFormat(temp).format(v));
          }

          2:數學方法
          public static double round2(double d, int scale) {
          long temp=1;
          for (int i=scale; i>;0; i--) {
          temp*=10;
          }
          d*=temp;
          long dl=Math.round(d);
          return (double)(dl)/temp;
          }

           

          鑒于網友的的指出,我重新認真研究了一下四舍五入,最終給出正確解法如下:

          import java.math.BigDecimal;
          import java.text.DecimalFormat;

          /**
          * 本例通過對網上幾種取四舍五入的研究,進行了一一測試。最終通過實驗和理論得出round4為唯一正確的算法。
          * 2008/10/13

          * @author jamezhan
          *
          */
          public class RoundTest {

          public static double round1(double v, int scale) {
          if (scale < 0)
          return v;

          String temp = "#####0.";
          for (int i = 0; i < scale; i++) {
          temp += "0";
          }

          return Double.valueOf(new java.text.DecimalFormat(temp).format(v));
          }

          /**
          * 該算法會出現中間運算后結果超過Double.MAX_VALUE,所以不推薦使用
          * @param d
          * @param scale
          * @return
          * @throws Exception
          */
          public static double round2(double d, int scale) throws Exception {
          if (scale < 0)
          return d;

          long temp = 1;
          for (int i = scale; i > 0; i--) {
          temp *= 10;
          }

          if (Math.abs(d * temp) > Double.MAX_VALUE)
          throw new Exception("data is too big or too small");

          d *= temp;
          long dl = Math.round(d);
          return (double) (dl) / temp;
          }

          public static double round3(double v, int scale) {
          BigDecimal value = new BigDecimal(v);
          float actualTax = value.setScale(scale, BigDecimal.ROUND_HALF_UP).floatValue();
          return actualTax;
          }

          public static double round4(double v,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();
          }

          public static void testRound1(double d, int scale) {
          System.out.println("==========================");
          System.out.println("data:"+ d + "; scale:"+scale);
          double a = round1(d, scale);
          System.out.println(a);

          DecimalFormat df = new DecimalFormat();
          System.out.println("formatted:"+df.format(a));
          }

          public static void testRound2(double d, int scale) {
          try {
          System.out.println("==========================");
          System.out.println("data:"+ d + "; scale:"+scale);
          double a = round2(d, scale);
          System.out.println(a);

          DecimalFormat df = new DecimalFormat();
          System.out.println("formatted:"+df.format(a));
          } catch (Exception e) {
          System.err.println( e.getMessage() );
          }
          }

          public static void testRound3(double d, int scale) {
          try {
          System.out.println("==========================");
          System.out.println("data:"+ d + "; scale:"+scale);
          double a = round3(d, scale);
          System.out.println(a);

          DecimalFormat df = new DecimalFormat();
          System.out.println("formatted:"+df.format(a));
          } catch (Exception e) {
          System.err.println( e.getMessage() );
          }
          }

          public static void testRound4(double d, int scale) {
          try {
          System.out.println("==========================");
          System.out.println("data:"+ d + "; scale:"+scale);
          double a = round4(d, scale);
          System.out.println(a);

          DecimalFormat df = new DecimalFormat();
          System.out.println("formatted:"+df.format(a));
          } catch (Exception e) {
          System.err.println( e.getMessage() );
          }
          }


          public static void main(String[] args) throws Exception {
          System.out.println("****************************** Test round1 ******************************");

          testRound1(Double.MAX_VALUE,2);
          testRound1(1.264,2);
          testRound1(-1.264,2);
          testRound1(1.265,2);//wrong result
          testRound1(-1.265,2);//wrong result
          testRound1(1.266,2);
          testRound1(-1.266,2);
          testRound1(10224948.265,2);//wrong result
          testRound1(-10224948.265,2);//wrong result
          testRound1(-Double.MAX_VALUE, 2);

          System.out.println("****************************** Test round2 ******************************");

          testRound2(Double.MAX_VALUE,2);
          testRound2(1.264,2);
          testRound2(-1.264,2);
          testRound2(1.265,2);//wrong result (java表示小數0.1的問題導致的 1.265表示為1.2599999904632568)
          testRound2(-1.265,2);//wrong result (由于round算法是先加0.5再運算,所以d為負數時且最后一位小數為5時結果是不正確的)
          testRound2(1.266,2);
          testRound2(-1.266,2);
          testRound2(10224948.265,2);
          testRound2(-10224948.265,2);//wrong result
          testRound2(-Double.MAX_VALUE, 2);


          System.out.println("****************************** Test round3 ******************************");

          testRound3(Double.MAX_VALUE,2);//wrong result 
          testRound3(1.264,2);
          testRound3(-1.264,2);
          testRound3(1.265,2);
          testRound3(-1.265,2);
          testRound3(1.266,2);
          testRound3(-1.266,2);
          testRound3(10224948.265,2);//wrong result 
          testRound3(-10224948.265,2);//wrong result
          testRound3(-Double.MAX_VALUE, 2);//wrong result 

          System.out.println("****************************** Test round4 ******************************");

          testRound4(Double.MAX_VALUE,2);
          testRound4(1.264,2);
          testRound4(-1.264,2);
          testRound4(1.265,2);
          testRound4(-1.265,2);
          testRound4(1.266,2);
          testRound4(-1.266,2);
          testRound4(10224948.265,2);
          testRound4(-10224948.265,2);
          testRound4(-Double.MAX_VALUE, 2);

          }
          }


           

          posted on 2006-04-25 11:38 翠竹 閱讀(12866) 評論(6)  編輯  收藏 所屬分類: java

          評論

          # re: java取四舍五入的方法 2006-05-30 14:26 rick

          呵呵,和我的大同小異:
          private double round2(double va) {
          // -------->運算四舍五入保留小數點2位
          va=Math.round(va*100.0);
          return va/100;
          }

          private double trunc2(double va){
          // -------->運算截斷保留小數點2位
          va=Math.floor(va*100.0);
          return va/100;
          }  回復  更多評論   

          # re: java取四舍五入的方法 2006-06-14 10:05 翠竹

          呵呵,就是!  回復  更多評論   

          # re: java取四舍五入的方法 2007-03-24 21:18 我賊帥

          樓主的算法不錯,你的只適合兩位小數...  回復  更多評論   

          # re: java取四舍五入的方法 2007-04-16 08:52 翠竹

          可以支持多位:@param scale 小數點后保留幾位   回復  更多評論   

          # re: java取四舍五入的方法 2007-09-19 09:21 longxibo

          lz有bug
          round(-10224948.26, 2)出問題
          round2一樣  回復  更多評論   

          # re: java取四舍五入的方法 2008-10-13 15:27 翠竹

          @longxibo
          對了,請你用round4方法。謝謝??!  回復  更多評論   

          主站蜘蛛池模板: 五常市| 库尔勒市| 疏附县| 绵阳市| 三明市| 桓台县| 兰州市| 临江市| 大宁县| 五华县| 慈利县| 宾阳县| 洛阳市| 吉林省| 乐至县| 靖安县| 三河市| 崇左市| 滦南县| 常德市| 汪清县| 碌曲县| 大埔县| 蒲城县| 九台市| 辰溪县| 鄯善县| 乐清市| 江达县| 枣强县| 通榆县| 镇江市| 邓州市| 麻城市| 章丘市| 怀宁县| 新竹县| 奇台县| 鹤峰县| 集安市| 雅安市|