0

Here is my current program where it asks the user to input the item they're buying and the original price. The program will take a random percent off (between 5-75) and then give the user the new total price including a .07 tax added. The code is working great just that I'm not sure how to get the price amount to round to $0.00 and not have trailing numbers which ends up affecting the coins/dollars that the cash register would give in change. Any ideas? Thanks!

import java.util.Scanner;
import java.lang.Math;
import java.math.*;
import java.util.Random;

//declaring variables for methods
class Main
{
    Scanner scan = new Scanner(System.in); 
    //random variable for while loop
    int k=1;
    //other variables
    String name;
    double taxRate = 0.07; 
    int dollars, quarters, dimes, nickels, cent, discountPercentage;
    double discount, salePrice, tax, totalPrice, money, change, originalPrice, cents;


  //method to run entire program
  public void runProgram()
  { 
    //make sure to create program including a while loop
    while (k<2)
    {
      //here it explains the calculations and gets the user input of the item and original price of it
      System.out.println("As part of a store promotion, each customer is given a random percent off");
      System.out.println("Please enter the name of the item you plan to purchase: ");
      name = scan.nextLine();
      System.out.println("Enter the original price of that item: "); 
      originalPrice = scan.nextDouble();
      scan.nextLine();

      //here is where the user input is being calculated
      discountPercentage = getDiscount();
      discount = calculateDiscount(originalPrice, discountPercentage);
      salePrice = calculateSalePrice(originalPrice, discount);
      tax = calculateTax(salePrice); 
      totalPrice = calculateTotalPrice(salePrice, tax); 

      //print to user all the new calculations of item price
      System.out.println("The original price of the item is: " + originalPrice); 
      System.out.println("The discount percent on the item is: " + discountPercentage + "%");
      System.out.println("The new sale price of the item is: " + salePrice);
      System.out.println("The tax of the item is: " + tax);
      System.out.println("Now, the new total price of the item including the discount and tax is: " + totalPrice); 

      //this part will figure out how much money the user is giving the cashier and how much change needs to be given
      System.out.println("How much money are you giving to the cashier?");
      money = scan.nextDouble();
      scan.nextLine(); 
      change = solveChange(money, totalPrice);
      System.out.println("The change you will be given back is: " + change);
      convertChange(change);
      System.out.println("\n");
    }
  }

  //method for getting random discount for the item
  public int getDiscount()
  {
    //discount can only be in multiples in 5 ranging from 5-75, and all the variables for this method
    int multiple = 5;
    int discountStart = 5;
    int discountEnd = 75;
    int calculateDiscountStart;
    int calculateDiscountEnd;

    calculateDiscountStart = discountStart / multiple;
    calculateDiscountEnd = discountEnd / multiple;
    
    //random generator for the discount
    discountPercentage = new Random().nextInt(1 + calculateDiscountEnd - calculateDiscountStart) + calculateDiscountStart; 

    return discountPercentage * multiple;
  }

  //method for calculating the discount percent that is applied to original price of item
  public double calculateDiscount(double originalPrice, int discountPercentage)
  {
    discount = originalPrice * discountPercentage / 100;
    return discount;
  }

  //method to calculate the price with the discount applied to the item
  public double calculateSalePrice(double originalPrice, double discount)
  {
    salePrice = originalPrice - discount;
    return salePrice; 
  }

  //method to calculate the tax 
  public double calculateTax(double salePrice)
  {
    tax = salePrice * taxRate;
    return tax;
  }

  //method that will calculate the overall price including tax (adding previous methods together)
  public double calculateTotalPrice(double salePrice, double tax)
  {
    totalPrice = salePrice + tax; 
    return totalPrice;
  }

  //method that takes user input of how much money giving and calculating how much change they need
  public double solveChange(double money, double totalPrice)
  {
    change = money - totalPrice; 
    //int dollars = change/1; 
    return change;
  }

  //method to convert the change the user needs to dollars, quarters, etc
  public double convertChange(double change)
  {
    cents = change*100; 
    dollars = (int)cents/100; 
    quarters = (int)(cents % 100)/25; 
    dimes = (int)((cents%100)%25)/10;
    nickels = (int)(((cents%100)%25)%10)/5; 
    cent = (int)((((cents%100)%25)%10)%5); 
    //printing out the amount of change to the user
    System.out.println("Amount of change in Dollars is: " + dollars);
    System.out.println("Amount of change in Quarters is: " + quarters);
    System.out.println("Amount of change in Nickels is: " + nickels);
    System.out.println("Amount of change in Dimes is: " + dimes);
    System.out.println("Amount of change in Cents is: " + cent);
    return change;
  }

  //main method using static 
  public static void main(String[] args) {
    Main prog = new Main();
    prog.runProgram();
  }
}
kcash
  • 1
  • 2
    You should use `BigDecimal` rather than primitive types for currency. Because the primitive type follow IEEE 754 floating point. They are bound to have rounding errors. If you don't care about accuracy at all? You can use `String format()` or `DecimalFormat` to make your numbers look neat. – Yoshikage Kira May 23 '21 at 22:51
  • Do not use floating point types like `float` or `double` for money values, this leads to problems. Use an integer type like `int` or `long` instead (by saving the total number of cents). – Progman May 23 '21 at 22:51
  • 1
    Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Yoshikage Kira May 23 '21 at 22:53

1 Answers1

0

What you usually do in real world programs that involve money: you use an int that is the total amount of pennies. So $ 1.99 = 199 int.

  • 1
    Generally [people prefer BigDecimal](https://stackoverflow.com/a/285707/2478398) so you can calculate percentage discounts, etc. without losing accuracy or having a (reasonably) limited upper value (BigDecimal is still limited… but not to a point expectable to encounter for money). – BeUndead May 23 '21 at 23:00
  • This advice is a bit crap for those new to java, and overkill for most situations: For example, BigDecimal is not just 'limited', it straight up __cannot__ divide 1 by 3. Try it. You'd have to explicitly pick some precision first, then it can, but now you have lost the ability to state that lossage or error due to rounding is impossible. Not all that much gained there. `int` (or `long`) is almost always the right answer. If it isn't, often BD isn't right either, it gets more complicated than even BD. – rzwitserloot May 23 '21 at 23:20
  • 1
    This is just plain wrong. BigDecimal is the normal way to do this. I've been developing financial apps for 30-years and we have a saying, "int or long is always wrong, and double is always trouble". Stick with BigDecimal and don't listen to anyone who tells you differently. – Software Engineer May 23 '21 at 23:20