Hey guys, I need some help with this coding. I feel like it's something simple so hopefully someone can figure it out. I know for certain that it has to do with float-int conversion problems, and I feel like once I figure that out the rest should fall into place. The code calculates the change due to a costumer by using this input file here.
Here's the source:

package cecs174;

import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class AssignmentFive
{
	static final String FNAME = "ass5input.txt";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		Scanner inFile = null;

		try
		{
			inFile = new Scanner(new File(FNAME));
		}
		catch(FileNotFoundException e)
		{
			System.out.println("Error: " + e.getMessage());
			System.out.println("Make sure " + FNAME + " is in the project's top level directory");
			System.exit(1);
		}
		 
		int count = inFile.nextInt();
		int checkSum = 0;
				
		for(int ii = 0; ii < count; ++ii)
		{
			float price = inFile.nextFloat();
			float paid = inFile.nextFloat();
			float change = price - paid;
			float origChange = change;
			
				
			System.out.print("Price: " + price + ", paid: " + paid + ", change: " + (price - paid) + ". Yields: ");
			if(change <= 0) System.out.println("No change required");
			else
			{
				int numTens = 0;
				int numFives = 0;
				int numOnes = 0;
				int numQuarters = 0;
				int numDimes = 0;
				int numNickels = 0;
				int numPennies = 0;
				
				numTens = change / 1000;
				change = change - (numTens * 1000);
				numFives = change / 500;
				change = change - (numFives * 500);
				numOnes = change / 100;
				change = change - (numOnes * 100);
				numQuarters = change / 25;
				change = change -(numQuarters * 25);
				numDimes = change / 10;
				change = change - (numDimes * 10);
				numNickels = change / 5;
				change = change - (numNickels * 5);
				numPennies = change / 1;
				change = change - (numPennies * 1);
					
				System.out.println(	"10's: " + numTens + ", " +
									"5's: " + numFives + ", " + 
									"1's: " + numOnes + ", " +
									"Qtrs: " + numQuarters + ", " +
									"Dimes: " + numDimes + ", " +
									"Nickels: " + numNickels + ", " +
									"Pennies: " + numPennies);
				
				if(	numTens * 1000 + 
					numFives * 500 + 
					numOnes * 100 + 
					numQuarters * 25 + 
					numDimes * 10 + 
					numNickels * 5 + 
					numPennies * 1 != (origChange)
				)	System.out.println("***** ERROR *****");
				
				checkSum += numTens + numFives + numOnes + numQuarters + numDimes
							+ numNickels + numPennies;
					
			} // end else

		} // end for
		
		System.out.println("Checksum: " + checkSum);
		inFile.close();
		
	} // end main
}

Edited 5 Years Ago by nickcolb: n/a

Change type of variables between line 44 and 50 from int to float. If you want to cast from float to int then you should do like this

int numTens = 0;
..
numTens = (int) change / 1000; //since change is float cast needed.

hope this is what you are looking for.

Change type of variables between line 44 and 50 from int to float. If you want to cast from float to int then you should do like this

int numTens = 0;
..
numTens = (int) change / 1000; //since change is float cast needed.

hope this is what you are looking for.

I probably should have posted the desired output...

Price: 1.0, paid: 0.01, change: 0.99. Yields: 10's: 0, 5's: 0, 1's: 0, Qtrs: 3, Dimes: 2, Nickels: 0, Pennies: 4
Price: 100.0, paid: 0.01, change: 99.99. Yields: 10's: 9, 5's: 1, 1's: 4, Qtrs: 3, Dimes: 2, Nickels: 0, Pennies: 4
Price: 1.0, paid: 0.75, change: 0.25. Yields: 10's: 0, 5's: 0, 1's: 0, Qtrs: 1, Dimes: 0, Nickels: 0, Pennies: 0
Price: 100.0, paid: 87.76, change: 12.239998. Yields: 10's: 1, 5's: 0, 1's: 2, Qtrs: 0, Dimes: 2, Nickels: 0, Pennies: 4
Checksum: 42

...but making the changes doesn't satisfy the code in line 82

oh! what you are doing is this.

change = 4.0;
numTens = change/1000; //i.e. 4/1000

change = change - (numTens *1000); // change = 4 - (4/1000 * 1000); //this would make change to be 0 because 4/1000 * 1000 is 4. (original value of change). 4-4 is 0.

now, there is a problem with your logic don't you think? Try to address this issue.
hope this helps.

//this would make change to be 0 because 4/1000 * 1000 is 4. (original value of change). 4-4 is 0.

Just to avoid any possible confusion here...

4/1000*1000 is not 4. Evaluation is all integer, left to right, ie
(4/1000)*1000
4/1000 in integer arithmetic is 0, so the intermediate value is
(0)*1000 which is zero.

4.0/1000*1000 is 4.0 because the arithmetic is done in float.

Just to avoid any possible confusion here...

4/1000*1000 is not 4. Evaluation is all integer, left to right, ie
(4/1000)*1000
4/1000 in integer arithmetic is 0, so the intermediate value is
(0)*1000 which is zero.

4.0/1000*1000 is 4.0 because the arithmetic is done in float.

There shouldn't be a problem because change would continue to be equal to 0 until it the code got to numPennies = change/1...which would be 4/1, but my problem seems to stem from some discrepancies between float to int conversion

Be very careful when you use float & int together. If you have float on your left hand side, you won't get a float when you use int in computation. Use double in place of float would make things easier but the rule is still the same.

float f;
double d;
int a=1, b=2;
f = a/b;  // won't get 0.5 but 0.0 here
d = a/b;  // won't get 0.5 either but 0.0 here

Need to look at your code...

OK, you should read JamesCherrill post again. You need to understand how computer stores float/double against int/long because it could still cause what it is not satisfied line 82.

In your code line 75 to 81, you attempt to compare an 'integer' with 'float' which is a NO NO. You could sometimes find that it is not true. Because float and double are estimated values, you must not use them to compare with int or long which is an exact value. Computer has limitation in decimal representation. Even though it is very small (10^-16 or epsilon value), it is still not equal.

Anyway, your total of changes will not be equal in your case. The reason is that your 'change' is in decimal while your total of changes is in full pennies. You should change it to...

int origChangeInt = (int) origChange*100;
int computedChange = (numTens * 1000 + numFives * 500 + numOnes * 100 + numQuarters * 25 + numDimes * 10 + numNickels * 5 + numPennies);
if( computedChange != origChangeInt)
  System.out.println("***** ERROR *****\nOriginal Changes: "+origChangeInt+"\nComputed Changes: "+computedChange);

PS: You should not add codes that won't do anything such as divide by 1 or multiply with 1. It does not do anything and it is not really intuitive. You may say that it would give a sense of penny but those who can read and understand code would be confused instead of see it that way. Also, when you display an error message, output all relevant variables used in the part you are checking. This way, you would get a better idea what goes wrong inside the code.

Edited 5 Years Ago by Taywin: n/a

Ok, with the help of my uncle I have gotten thus far...

The desired output:

Price: 1.0, paid: 0.01, change: 0.99. Yields: 10's: 0, 5's: 0, 1's: 0, Qtrs: 3, Dimes: 2, Nickels: 0, Pennies: 4
Price: 100.0, paid: 0.01, change: 99.99. Yields: 10's: 9, 5's: 1, 1's: 4, Qtrs: 3, Dimes: 2, Nickels: 0, Pennies: 4
Price: 1.0, paid: 0.75, change: 0.25. Yields: 10's: 0, 5's: 0, 1's: 0, Qtrs: 1, Dimes: 0, Nickels: 0, Pennies: 0
Price: 100.0, paid: 87.76, change: 12.239998. Yields: 10's: 1, 5's: 0, 1's: 2, Qtrs: 0, Dimes: 2, Nickels: 0, Pennies: 4
Checksum: 42

My current output:

Price: 1.0, paid: 0.01, change: 0.99. Yields: 10's: 0, 5's: 0, 1's: 0, Qtrs: 3, Dimes: 2, Nickels: 0, Pennies: 4
Price: 100.0, paid: 0.01, change: 99.99. Yields: 10's: 9, 5's: 1, 1's: 4, Qtrs: 3, Dimes: 2, Nickels: 0, Pennies: 4
Price: 1.0, paid: 0.75, change: 0.25. Yields: 10's: 0, 5's: 0, 1's: 0, Qtrs: 1, Dimes: 0, Nickels: 0, Pennies: 0
Price: 100.0, paid: 87.76, change: 12.239998. Yields: 10's: 1, 5's: 0, 1's: 2, Qtrs: 0, Dimes: 2, Nickels: 0, Pennies: 3
change = [0.99975586] origChange = [1223.9998]***** ERROR *****
Checksum: 41

The similarities give me hope but frustrate me at the same time.

This is also my updated code:

package cecs174;

import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class AssignmentFive
{
	static final String FNAME = "ass5input.txt";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{
		Scanner inFile = null;

		try
		{
			inFile = new Scanner(new File(FNAME));
		}
		catch(FileNotFoundException e)
		{
			System.out.println("Error: " + e.getMessage());
			System.out.println("Make sure " + FNAME + " is in the project's top level directory");
			System.exit(1);
		}
		 
		int count = inFile.nextInt();
		int checkSum = 0;
				
		for(int ii = 0; ii < count; ++ii)
		{
			float price = inFile.nextFloat();
			float paid = inFile.nextFloat();
			float change = price - paid;
			change = change * 100;
			float origChange = change;
						
				
			System.out.print("Price: " + price + ", paid: " + paid + ", change: " + (price - paid) + ". Yields: ");
			if(change <= 0) System.out.println("No change required");
			else
			{
				int numTens = 0;
				int numFives = 0;
				int numOnes = 0;
				int numQuarters = 0;
				int numDimes = 0;
				int numNickels = 0;
				int numPennies = 0;
				
				numTens = new Float(change / 1000).intValue();
				change = change - (numTens * 1000);
				numFives = new Float(change / 500).intValue();
				change = change - (numFives * 500);
				numOnes = new Float(change / 100).intValue();
				change = change - (numOnes * 100);
				numQuarters = new Float(change / 25).intValue();
				change = change -(numQuarters * 25);
				numDimes = new Float(change / 10).intValue();
				change = change - (numDimes * 10);
				numNickels = new Float(change / 5).intValue();
				change = change - (numNickels * 5);
				numPennies = new Float(change / 1).intValue();
				change = change - (numPennies * 1);
					
				System.out.println(	"10's: " + numTens + ", " +
									"5's: " + numFives + ", " + 
									"1's: " + numOnes + ", " +
									"Qtrs: " + numQuarters + ", " +
									"Dimes: " + numDimes + ", " +
									"Nickels: " + numNickels + ", " +
									"Pennies: " + numPennies);
				
				if(	numTens * 1000 + 
					numFives * 500 + 
					numOnes * 100 + 
					numQuarters * 25 + 
					numDimes * 10 + 
					numNickels * 5 + 
					numPennies * 1 != (origChange)
				)	System.out.println("change = [" + change + "]" + " origChange = [" + origChange + "]" + "***** ERROR *****");
				
				checkSum += numTens + numFives + numOnes + numQuarters + numDimes
							+ numNickels + numPennies;
					
			} // end else

		} // end for
		
		System.out.println("Checksum: " + checkSum);
		inFile.close();
		
	} // end main
}

Edited 5 Years Ago by nickcolb: n/a

OK... I converted everything to int before I do the computation in order to avoid the decimal effect. Of course, I expect that the 'price' and 'paid' are in dollar. Try this...

import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class AssignmentFive {
  static final String FNAME = "ass5input.txt";
  
  /**
   * @param args
   */
  public static void main(String[] args)  {
    Scanner inFile = null;

    try  {
      inFile = new Scanner(new File(FNAME));
    }
    catch(FileNotFoundException e) {
      System.out.println("Error: " + e.getMessage());
      System.out.println("Make sure " + FNAME + " is in the project's top level directory");
      System.exit(1);
    }
     
    int count = inFile.nextInt();
    int checkSum = 0;
        
    for(int ii = 0; ii < count; ++ii)  {
      int price = (int) (inFile.nextFloat() *100); // in cent
      int paid = (int) (inFile.nextFloat()*100);   // in cent
      int change = price - paid; // in cents
      int origChange = change;  // keep the record

      System.out.print("Price: " + (float) price/100);
      System.out.print(", paid: " + (float) paid/100);
      System.out.print(", change: " + (float) change/100 + ". Yields: ");
      if(origChange <= 0) System.out.println("No change required");
      else {
        int numTens = 0;
        int numFives = 0;
        int numOnes = 0;
        int numQuarters = 0;
        int numDimes = 0;
        int numNickels = 0;
        int numPennies = 0;
        
        numTens = change / 1000;     // $10
        change -= (numTens * 1000);
        numFives = change / 500;     // $5
        change -= (numFives * 500);
        numOnes = change / 100;      // $1
        change -= (numOnes * 100);
        numQuarters = change / 25;   // 25c
        change -= (numQuarters * 25);
        numDimes = change / 10;      // 10c
        change -= (numDimes * 10);
        numNickels = change / 5;     // 5c
        change -= (numNickels * 5);
        numPennies = change;         // 1c
          
        System.out.println(  "10's: " + numTens + ", " +
                  "5's: " + numFives + ", " + 
                  "1's: " + numOnes + ", " +
                  "Qtrs: " + numQuarters + ", " +
                  "Dimes: " + numDimes + ", " +
                  "Nickels: " + numNickels + ", " +
                  "Pennies: " + numPennies);
        
        if(  numTens * 1000 + 
          numFives * 500 + 
          numOnes * 100 + 
          numQuarters * 25 + 
          numDimes * 10 + 
          numNickels * 5 + 
          numPennies * 1 != (origChange)
        )  System.out.println("change = [" + change + "]" + " origChange = [" + origChange + "]" + "***** ERROR *****");
        
        checkSum += numTens + numFives + numOnes + numQuarters + numDimes
              + numNickels + numPennies;
          
      } // end else

    } // end for

    System.out.println("Checksum: " + checkSum);
    inFile.close();

  } // end main
}

Edited 5 Years Ago by Taywin: n/a

Oh I forgot to explain why you got the wrong result... Here is what happened. Please look at the code & result below.

// relevant code part
  int numPennies = 0;
  numPennies = new Float(change / 1).intValue();
  change = change - (numPennies * 1);

// result
change = [0.99975586] origChange = [1223.9998]***** ERROR *****

/*
example when the program executed to the numPennies assignment.
  change = 0.99975586
  numPennies = 0.99975586/1  then
  numPennies = 0   because integer will truncate all decimals
  change = change - (0*1)
  change = 0.99975586

As a result, you get the result above.
*/

Nicely done Taywin.

A really good example of why you should store money an int or long of cents, rather than float or double.

This article has been dead for over six months. Start a new discussion instead.