【问题标题】:Giving wrong number when giving change using %使用 % 找零时给出错误的数字
【发布时间】:2015-09-22 12:02:18
【问题描述】:

我正在创建一个回馈变化的系统。当我运行程序时,我得到: (假设我给了 100 美元)

You have given 100.0 dollars.
Your change is 14.670000000000002 dollars.
You will recieve:
0.6700000000000017 dollars
0.1700000000000017 quarters
0.0700000000000017 dimes
0.020000000000001697 nickels
1.6965595595053173E-15 pennies

代码

import java.util.Scanner;
public class RunGivingChange {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        double given;
        double cost = 85.33;
        double change;
        int dollars;
        int quarters;
        int dimes;
        int nickels;
        int pennies;

        Scanner input = new Scanner(System.in);

        System.out.println("Your total is " + cost + " dollars.");
        System.out.println("How much money are you giving?");
        given = input.nextDouble();
        if (given >= cost)
        {
            System.out.println("You have given " + given + " dollars.");
            change = given - cost;
            System.out.println("Your change is " + change + " dollars.");
            System.out.println("You will recieve:");

            //dollars
            change = change % 1;
            System.out.println(change + " dollars");

            //quarters
            change = change % 0.25;
            System.out.println(change + " quarters");

            //dimes
            change = change % 0.10;
            System.out.println(change + " dimes");

            //nickels
            change = change % 0.05;
            System.out.println(change + " nickels");

            //pennies
            change = change % 0.01;
            System.out.println(change + " pennies");
        }
        else if (given < cost)
        {
            System.out.println("Not enough money.");
        }
        else
        {
            System.out.println("Error.");
        }

    }

    }

【问题讨论】:

  • 至少对您的下一个问题提出建议/要求:尽可能具体。 It's giving the wrong number 没有多大帮助。至少我们需要知道您认为错误的是什么:是精度、计算结果还是其他原因?

标签: java currency


【解决方案1】:

您正在使用双精度浮点值来表示货币。

不要那样做。

浮点数为您提供大约 15 个有效数字的准确度,但具有惊人的范围(和计算性能),使其可用于科学用途。

使用定点类型或 BigDecimal 作为货币值。

【讨论】:

  • 是的,这很实用,但不要忘记对“美元”有 1,000“美分”的货币,例如突尼斯第纳尔。这可以“吃掉”你的很多整数。您可以使用 64 位但不是 32。
  • 我会使用 joda-money 库而不是重新发明轮子
【解决方案2】:

Modulo (%) 无法按预期工作(除了精度问题):

2.67 % 1 不会导致2,而是0.67

(更多信息请看这里:How do I use modulus for float/double?

您可能想要计算Math.floor( 2.67 / 1) 等并从change 中减去四舍五入的值。

或者,如果change 始终为正(应该是),您可以将其强制转换(并因此削减)为整数:

int dollars = (int)(change / 1);
change -= dollars;

int quarters = (int)(change / 0.25);
change -= 0.25 * quarters;

...

要克服精确问题,请使用 BigDecimal 或将所有值转换为便士,即零钱 = 1467 便士、1 美元 = 100 便士等。

【讨论】:

    【解决方案3】:

    您可以用最小的单位(便士)来表示成本,而不是用美元表示:

    double cost = 85.33;// dollars
    you could express it as :
    int cost = 8533: .. //pennies
    

    然后您可以使用/% 操作序列来计算每个货币除法。 例如:

    int dollars = change / 100; // how many dollars fit in that pennies amount
    change = change % 100; // how much pennies are left
    
    //repeat for the other subdivisions
    

    【讨论】:

      【解决方案4】:

      如果您使用双精度,请确保四舍五入到小数位。

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

      其次,mod (%) 返回语句的剩余部分

      14.67 % 1.0 = 0.67

      你首先要做的是找出 1.0 将分成多少次 14。

      dollars = Math.floor(change / 1);
      change = change % 1.0;
      

      这将向下舍入到最接近的整数,并告诉您 1.0 可以进行多少次更改。

      这里使用 double 的问题就像 Bathsheba 所说的那样。 要解决此问题,您必须在每次修改更改后进行舍入。

      这应该会给你正确的输出。

      import java.util.Scanner;
      
      public class RunGivingChange{
      
      
          public static void main(String[] args) {
      
      
              double given;
              double cost = 85.33;
              double change;
              int dollars;
              int quarters;
              int dimes;
              int nickels;
              int pennies;
      
              Scanner input = new Scanner(System.in);
      
              System.out.println("Your total is " + cost + " dollars.");
              System.out.println("How much money are you giving?");
              given = input.nextDouble();
              if (given >= cost) {
                  System.out.println("You have given " + given + " dollars.");
                  change = given - cost;
                  // round the change
                  change = (double) Math.round(change *100) / 100;
                  System.out.println("Your change is " + change + " dollars.");
                  System.out.println("You will recieve:");
      
                  //dollars     
      
                  System.out.println(Math.floor(change / 1) + " dollars");
                  change = change % 1;
                  change = (double) Math.round(change *100) / 100;
                  //quarters
      
                  System.out.println(Math.floor(change / 0.25) + " quarters");
                  change = change % 0.25;
                  change = (double) Math.round(change *100) / 100;
                  //dimes
      
                  System.out.println(Math.floor(change / 0.1) + " dimes");
                  change = change % 0.10;
                  change = (double) Math.round(change *100) / 100;
                  //nickels
      
                  System.out.println(Math.floor(change / 0.05) + " nickels");
                  change = change % 0.05;
                  change = (double) Math.round(change *100) / 100;
                  //pennies
      
                  System.out.println(Math.floor(change / 0.01) + " pennies");
      
              } else if (given < cost) {
                  System.out.println("Not enough money.");
              } else {
                  System.out.println("Error.");
              }
      
          }
      
      }
      

      有更好的方法可以做到这一点,下次您应该搜索该网站。这个话题有多个答案。

      How to convert money to change

      Compute the different ways to make (money) change from $167.37?

      Show money in change

      【讨论】:

        猜你喜欢
        • 2020-02-12
        • 1970-01-01
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-04
        • 2014-07-27
        • 1970-01-01
        相关资源
        最近更新 更多