【问题标题】:How do I round up currency values in Java?如何在 Java 中四舍五入货币值?
【发布时间】:2012-09-20 06:04:41
【问题描述】:

好的,这是我的问题。 基本上我有这个问题。

我有一个像 0.53999999 这样的数字。 如何在不使用任何数学函数的情况下将其四舍五入到 54?

我猜我必须乘以 100 来缩放它,然后除以? 类似的东西?


问题在于钱。假设我有 50.5399999 美元,我知道如何获得 50 美元,但我不知道如何获得美分。我可以得到 .539999 部分,但我不知道如何将其变为 54 美分。

【问题讨论】:

  • 我建议将标题更改为:“如何在 Java 中四舍五入货币值?”这样,这个问题就更适合寻找答案的人了——你会得到我的支持;)

标签: java currency rounding


【解决方案1】:

我会使用类似的东西:

BigDecimal result = new BigDecimal("50.5399999").setScale(2, BigDecimal.ROUND_HALF_UP);

JavaWorld 上有一篇名为 Make cents with BigDecimal 的精彩文章,您应该看看。

【讨论】:

  • 我更喜欢你的第一反应。
  • BigDecimal 确实是答案
  • 第一个答案有什么用?:int i = ( int ) ( x + .5 )
  • 不确定您在问什么?我更改了答案,因为问题已被编辑。
【解决方案2】:

您应该使用小数或货币类型来表示货币,而不是浮点数。

【讨论】:

  • 是的,浮点货币存储经过一些计算会导致非常糟糕的事情。
  • 这很重要!永远不要用浮点数来赚钱!坏事会发生
  • 将货币存储为多头(美分数)
  • 分数美分怎么样(涉及金钱百分比的计算可能会产生分数美分)。
  • @Albert:大多数货币类型都可以处理这个问题。否则使用另一种十进制类型,或 1/100 美分的长数。
【解决方案3】:

用金钱做数学比大多数工程师想象的要复杂(过度概括)

如果您进行货币计算,我认为您可能正在研究表面上看起来简单但实际上相当复杂的问题。例如,由于业务逻辑决策经常重复而产生的舍入方法会极大地影响计算总数。

如果这是家庭作业,向老师展示您已经思考了现实世界的问题,而不是仅仅将一堆“有效”的代码拼凑在一起 - 肯定会更令人印象深刻。

顺便说一句,我最初打算建议查看源代码中 Java 数学方法的实现,所以我看了一下。我注意到 Java 在其舍入方法中使用了本机方法 - 就像它应该做的那样。

但是,查看 BigDecimal 表明存在可用于在 Java 中进行舍入的 Java 源代码。因此,我建议您查看 Java 源代码中的 BigDecimal 私有方法 doRound(MathContext mc),而不仅仅是给您作业的代码。

【讨论】:

  • Currency 类实际上不进行任何格式化,也不存储任何货币值;它只包含一些关于货币属性的信息,其中 getDefaultFractionDigits() 是这里唯一真正相关的信息(并且无论如何都会重复问题中的信息)。
【解决方案4】:

如果 50.54 不能以双精度表示,则舍入将无济于事。

如果您尝试将 50.53999999 转换为整数美元和整数美分,请执行以下操作:

double d = 50.539999; // or however many 9's, it doesn't matter
int dollars = (int)d;
double frac = d - dollars;
int cents = (int)((frac * 100) + 0.5);

请注意,在最后一步中加上 0.5 是为了四舍五入到 最接近的美分整数。如果您总是希望它向上取整,请将其更改为添加 0.9999999 而不是 0.5。

【讨论】:

    【解决方案5】:

    您为什么不想使用任何数学函数?

    static long round(double a) 
    

    - 返回最接近参数的 long。

    http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html

    为了代表金钱,我会接受以下建议,而不是重新发明轮子:

    http://www.javapractices.com/topic/TopicAction.do?Id=13

    【讨论】:

    • 问题是我们没有讨论任何关于“静态”和“圆形”的内容。问题在于钱。假设我有 50.5399999 美元,我知道如何获得 50 美元,但我不知道如何获得美分。我可以得到 .539999 部分,但我不知道如何将其变为 54 美分。
    • 我添加了一个关于用 Java 表示金钱的注释
    【解决方案6】:

    尝试将您的货币存储为美分数(您可以将其抽象为基本货币单位数)并使用 long。

    编辑:由于这是家庭作业,您可能无法控制类型。将此视为未来项目的教训

    long money = 5054;
    
    long cents = money % 100;
    long dollars = money / 100; // this works due to integer/long truncation
    
    System.out.printf("$%d.%02.d", dollars, cents);
    

    【讨论】:

      【解决方案7】:

      您需要将数字设为 0.535,然后将其与您的原始数字进行比较,看看您是向上取整还是向下取整。以下是从 .53999999 获得 .535 的方法(应该适用于任何数字):

      num = .53999999;
      int_num = (int)(num * 100); // cast to integer, however you do it in Java
      compare_num = (int_num + 0.5) / 100;
      

      compare_num 在这种情况下为 0.535。如果num 大于或等于compare_num,则向上舍入到int_num + 1。否则简单地向下舍入到int_num

      【讨论】:

      • 对于那些假设“向上取整”意味着“总是向上取整”的人......可能是这样,是的。只需将@Ruten 示例中的 0.5 替换为 0.9999999 ... 或者,取反并向下取整,然后再次取反。
      【解决方案8】:

      Sean 似乎拥有它,但如果你想施加适当的规则,那么你可能需要像这样抛出一个 if 语句:

      double value = .539999;
      int result = (int) (value*100);
      if(((value*100)%result)>.5)
          result++;
      

      【讨论】:

      • 我希望人们能评论他们为什么不投票,我不明白这不是可接受的代码......
      • @gnomed:同意:downvote 应该得到评论。对我来说看起来不错,所以一个。唯一的改进是将其打包为一个函数,并将精度作为参数传递。
      【解决方案9】:

      我建议您使用 long 来舍入双精度值。对小数字没关系,但可能会有所作为。

      double d = 50.539999;
      long cents = (long)(d * 100 + 0.5);
      double rounded = cents/100;
      

      【讨论】:

        【解决方案10】:

        你到底想做什么?您是否总是试图达到两位数?还是无论如何,您总是试图在最后修复 99999 之类的问题?

        根据 cmets,实际上是前者:四舍五入为美元和美分。所以确实只是round(100*a)/100 是你想要的。 (后者会复杂得多……)

        最后,如果你只是想提取美分​​部分,以下方法可行:

        dollars_and_cents = round(100*a)/100
        cents = (dollars_and_cents-(int)dollars_and_cents)*100
        

        (或者java是否只有frac?在这种情况下,最后一行将是frac(dollars_and_cents)*100

        【讨论】:

        • 我在第一个回复中评论了我到底想要做什么。 “问题在于钱。假设我有 50.5399999 美元,我知道如何获得 50 美元,但我不知道如何获得美分。我可以获得 .539999 部分,但我不知道如何获得它到 54 美分。”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-14
        • 2011-09-10
        • 2020-04-08
        • 2010-11-13
        • 1970-01-01
        • 2011-10-01
        • 1970-01-01
        相关资源
        最近更新 更多