【问题标题】:Java rounding issuesJava 舍入问题
【发布时间】:2011-08-23 07:50:01
【问题描述】:

我正在使用以下代码对作为输入给出的浮点值进行舍入。但我做错了。如果我给 80 美元,我应该得到 80.00 美元,如果我给 40.009889 美元,我应该得到 40.01 美元。我该怎么做?

公共课轮{ 公共静态浮点round_this(浮点数){ //浮点数 = 2.954165f; 浮点数 = Round(num,2); 轮回; } 私有静态浮点 Round(float Rval, int Rpl) { 浮动 p = (float)Math.pow(10,Rpl); Rval = Rval * p; 浮动 tmp = Math.round(Rval); 返回(浮动)tmp/p; } }

【问题讨论】:

    标签: java


    【解决方案1】:

    这就是为什么您不使用浮点数来赚钱的原因,因为您会陷入“垃圾输入,数据输出”的游戏中。请改用 java.math.BigDecimal。 BigDecimal 可让您指定不受表示问题影响的固定十进制值。

    (当我说不要使用包含双精度的浮点数时,这是同一个问题。)

    这是一个例子。我创建了两个 BigDecimal 数字。对于第一个,我使用带有浮点数的构造函数。对于第一个,我使用带有字符串的构造函数。在这两种情况下,BigDecimal 都会向我显示它所持有的数字:

    groovy:000> f = new BigDecimal(1.01)
    ===> 1.0100000000000000088817841970012523233890533447265625
    groovy:000> d = new BigDecimal("1.01")
    ===> 1.01
    

    更多解释见this questiona good answer here还有另一个问题。

    【讨论】:

    • 正是...查看该相关列表---------->中的任何内容
    【解决方案2】:

    来自The Floating-Point Guide

    为什么我的数字不是 0.1 + 0.2 加起来是一个不错的 0.3 轮,并且 相反,我得到了一个奇怪的结果,比如 0.30000000000000004?

    因为在内部,计算机使用 格式(二进制浮点) 不能准确地表示一个数字 像 0.1、0.2 或 0.3 一样。

    当代码被编译或 解释,你的“0.1”已经 四舍五入到最接近的数字 格式,这会导致一个小 舍入误差甚至在 计算发生。

    【讨论】:

      【解决方案3】:

      使用BigDecimal class 代替浮点数。

      并像这样使用 Java 代码:

      BigDecimal bd = new BigDecimal(floatVal);
      bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
      

      【讨论】:

        【解决方案4】:

        我不会使用float,我建议使用doubleintlong 或(如果必须)BigDecimal

        private static final long[] TENS = new long[19];
        static {
            TENS[0] = 1;
            for (int i = 1; i < TENS.length; i++) TENS[i] = TENS[i - 1] * 10;
        }
        public static double round(double x, int precision) {
            long tens = TENS[precision];
            long unscaled = (long) (x < 0 ? x * tens - 0.5 : x * tens + 0.5);
            return (double) unscaled / tens;
        }
        

        这并不能给出所有分数的精确答案,因为浮点数无法做到这一点,但它会给你一个正确打印的答案。

        double num = 2.954165;
        double round = round(num, 2);
        System.out.println(round);
        

        打印

        2.95
        

        【讨论】:

          【解决方案5】:

          这样就可以了。

           public static void main(String[] args) {
              double d = 12.349678;
              int r = (int) Math.round(d*100);
              double f = r / 100.0;
             System.out.println(f);
           }
          

          这个方法可以简写,很容易理解所以我写成这样

          【讨论】:

          • @Ankit:用double而不是float,还是不适合花钱。
          • @Jon Skeet,但在我的经验中,double 是大多数投资银行使用的。
          • @Ankit:嗯,不。能够准确地表示像“10.01”这样的值是很有用的……这是 double 不能做到的。这就是首选 BigDecimal 的原因。
          • @Ankit:这段代码的问题在于它不起作用。它行不通。 .01 不能准确地用双精度表示,因此它不可能返回该值。试试吧。而 double 完全没用“就金钱而言”。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-15
          • 1970-01-01
          • 2013-04-12
          • 2011-04-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多