# Change-Making Problem Solution

Please take a moment and review my code and tell me how I did. This is the first time in my class (CSC 111) I've been given an assignment in which I had to use a lot of my own resources and develop most of it on my own.

Write an application that prompts for and reads a double value representing a monetary amount. Then determine the least number of each bill and coin needed to represent that amount, starting with the highest. Assume that ten dollars is the maximum size needed. For example, if the value 47.63 is entered the program should display

• 4 ten dollar bills
• 1 five dollar bills
• 2 one dollar bills
• 2 quarters
• 1 dimes
• 0 nickels
• 3 pennies

My code works mostly flawlessly (I believe). I would like to hear other people's opinion on my solution. I understand it probably isn't the most efficient out there. How can it be improved? Are there things to watch out for?

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Scanner;
import java.util.Locale;

public class Assignment01
{
public static void main(String[] args)
{

/* Define Constants */

BigDecimal tenDollar = BigDecimal.valueOf(10);
BigDecimal fiveDollar = BigDecimal.valueOf(5);
BigDecimal oneDollar = BigDecimal.valueOf(1);
BigDecimal quarter = BigDecimal.valueOf(0.25);
BigDecimal dime = BigDecimal.valueOf(0.10);
BigDecimal nickel = BigDecimal.valueOf(0.05);
BigDecimal penny = BigDecimal.valueOf(0.01);

/* Get Input From User */

System.out.print("Please enter the amount to be converted: ");
Scanner scan = new Scanner(System.in);
BigDecimal money = scan.nextBigDecimal();

NumberFormat usdFormat = NumberFormat.getCurrencyInstance(Locale.US);
usdFormat.setMinimumFractionDigits(2);
usdFormat.setMaximumFractionDigits(2);

System.out.println("Amount you entered: " + usdFormat.format(money));

/* Begin Processing and Displaying Information */

BigDecimal tenDollarNext = money.divideToIntegralValue(tenDollar);
System.out.println(tenDollarNext.intValue() + " Ten Dollar Bills");

BigDecimal fiveDollarNext = money.subtract(tenDollar.multiply(tenDollarNext));
BigDecimal i = fiveDollarNext.divide(fiveDollar);
System.out.println(i.intValue() + " Five Dollar Bills");

BigDecimal oneDollarNext = fiveDollarNext.subtract(fiveDollar.multiply(BigDecimal.valueOf(i.intValue())));
BigDecimal f = oneDollarNext.divide(oneDollar);
System.out.println(f.intValue() + " One Dollar Bills");

BigDecimal quarterNext = oneDollarNext.subtract(oneDollar.multiply(BigDecimal.valueOf(f.intValue())));
BigDecimal q = quarterNext.divide(quarter);
System.out.println(q.intValue() + " Quarters");

BigDecimal dimeNext = quarterNext.subtract(quarter.multiply(BigDecimal.valueOf(q.intValue())));
BigDecimal d = dimeNext.divide(dime);
System.out.println(d.intValue() + " Dimes");

BigDecimal nickelNext = dimeNext.subtract(dime.multiply(BigDecimal.valueOf(d.intValue())));
BigDecimal n = nickelNext.divide(nickel);
System.out.println(n.intValue() + " Nickels");

BigDecimal pennyNext = nickelNext.subtract(nickel.multiply(BigDecimal.valueOf(n.intValue())));
BigDecimal p = pennyNext.divide(penny);
System.out.println(p.intValue() + " Pennies");

}
}

• Using BigDecimal is probably over-engineering things. For this scale of problem it is usually better to work in cents, not dollars, and use either int or long to hold the number of cents. An int will go up to $21,474,836.47 while a long will go up to$92,233,720,368,547,758.07. Given the nature of the problem, I suspect an int will be sufficient. – rossum Feb 9 '17 at 14:13

    BigDecimal money = scan.nextBigDecimal();


The specification said

reads a double value representing a monetary amount.

However, BigDecimal is the correct type to represent a monetary amount. There's a case to be made for using scan.nextDouble() to comply with the spec and then converting it to BigDecimal. There's also a case to be made that you should talk to the person who set the task and suggest improving the spec.

    BigDecimal tenDollarNext = money.divideToIntegralValue(tenDollar);
System.out.println(tenDollarNext.intValue() + " Ten Dollar Bills");

BigDecimal fiveDollarNext = money.subtract(tenDollar.multiply(tenDollarNext));
BigDecimal i = fiveDollarNext.divide(fiveDollar);


Why the inconsistencies? tenDollarNext and fiveDollarNext aren't analogues of each other, and one uses divideToIntegralValue(...) where the other uses divide(...).intValue().

There are seven chunks of code dealing with seven values of token which are virtually identical. DRY: use a loop.