Thread: Possible Issue with Float?

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    5

    Possible Issue with Float?

    Okay, I have to make a program using a function with the parameters below in order to allow someone to enter an ammount of money, and then calculate which coins could make up that ammount of money.
    Code:
    void change(int *nC, double vC, double *amt)
    I've wrote the program, which is below here, but for some reason at certain values, such as 3 cents, the pennies are off by 1 or 2. I have a feeling it has something to do with the inacuracy of the floating point numbers and the >=, but no matter what I've done to get around that the results don't change. I tried setting it to run while the amt > 0 and then having the first thing in the while loop being an if statment saying that if amt < vC return; but that produced the same results.

    Any information on where I've gone wrong would be great, thank you.

    Code:
    #include <math.h>
    #include <stdio.h>
    	void change(int *nC, double vC, double *amt);
    
    	void main()
    	{
    		double z;
    		int nH,nQ,nD,nN,nP;
    		double vH = .50, vQ = .25, vD = .10, vN = .05, vP = .01;
    		printf("Enter an ammount of money: ");
    		scanf("%lf",&z);
    		while(z > 0)
    		{
    			change(&nH,vH,&z);
    			change(&nQ,vQ,&z);
    			change(&nD,vD,&z);
    			change(&nN,vN,&z);
    			change(&nP,vP,&z);
    			printf("Number of Half Dollars: %d\nNumber of Quarters: %d\nNumber of Dimes: %d\nNumber of Nickels: %d\nNumber of Pennies: %d\n",nH,nQ,nD,nN,nP);
    			printf("Enter an ammount of money: ");
    			scanf("%lf",&z);
    		}
    	}
    	
    	void change(int *nC, double vC, double *amt)
    	{
    		*nC = 0;
    		while(*amt >= vC)
    		{
    			*amt = *amt - vC;
    			*nC = *nC + 1;
    		}
    	}

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by nate92488 View Post
    I've wrote the program, which is below here, but for some reason at certain values, such as 3 cents, the pennies are off by 1 or 2. I have a feeling it has something to do with the inacuracy of the floating point numbers and the >=, but no matter what I've done to get around that the results don't change.
    Your analysis is correct. Floating point values are the wrong way to do this. Maybe the purpose of this assignment is to demonstrate this fact to you.

    On the other hand, if the instructor is really requiring you to do it this way, that person is an idiot who shouldn't be teaching people.

    EDIT: You could make it work by using the values 50, 25, 10, 5, 1 instead of of the decimal equivalents. Then do everything in cents instead of dollars. Integer values can always be represented exactly in floating point.
    Last edited by brewbuck; 04-25-2007 at 12:16 PM.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    5
    Quote Originally Posted by brewbuck View Post
    Your analysis is correct. Floating point values are the wrong way to do this. Maybe the purpose of this assignment is to demonstrate this fact to you.

    On the other hand, if the instructor is really requiring you to do it this way, that person is an idiot who shouldn't be teaching people.
    Okay, perhaps he was trying to show us the issue with floating point numbers.. but it certainly is a cruel way to do it. Spent many hours changing things trying to get the answer to always come out right, but absolutely nothing seems to do it.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by nate92488 View Post
    Okay, perhaps he was trying to show us the issue with floating point numbers.. but it certainly is a cruel way to do it. Spent many hours changing things trying to get the answer to always come out right, but absolutely nothing seems to do it.
    Try the other thing I suggested. Multiply the dollar amount by 100 to turn it into cents, then do everything in cents. Now that everything is an integer, the pointlessness of using floats for this will be revealed ;-)

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    5
    Quote Originally Posted by brewbuck View Post
    Try the other thing I suggested. Multiply the dollar amount by 100 to turn it into cents, then do everything in cents. Now that everything is an integer, the pointlessness of using floats for this will be revealed ;-)
    I actually tried that as well, but still got in wrong results for some higher values such a .29. Here's the code I used to do it that way:

    Code:
    #include <math.h>
    #include <stdio.h>
    	void change(int *nC, double vC, double *amt);
    
    	void main()
    	{
    		double z;
    		int nH,nQ,nD,nN,nP;
    		double vH = 50, vQ = 25, vD = 10, vN = 5, vP = 1;
    		printf("Enter an ammount of money: ");
    		scanf("&#37;lf",&z);
    		while(z > 0)
    		{
    			z = z * 100;
    			change(&nH,vH,&z);
    			change(&nQ,vQ,&z);
    			change(&nD,vD,&z);
    			change(&nN,vN,&z);
    			change(&nP,vP,&z);
    			printf("Number of Half Dollars: %d\nNumber of Quarters: %d\nNumber of Dimes: %d\nNumber of Nickels: %d\nNumber of Pennies: %d\n",nH,nQ,nD,nN,nP);
    			printf("Enter an ammount of money: ");
    			scanf("%lf",&z);
    		}
    	}
    	
    	void change(int *nC, double vC, double *amt)
    	{
    		*nC = 0;
    		while(*amt >= vC)
    		{
    			*amt = *amt - vC;
    			*nC = *nC + 1;
    		}
    	}
    Last edited by nate92488; 04-25-2007 at 12:24 PM.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by nate92488 View Post

    Code:
    z = z * 100;
    There can be inaccuracy here. Round the value to the nearest integer number of cents first:

    Code:
    z = (double)(int)(z * 100 + 0.5);

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    5
    Quote Originally Posted by brewbuck View Post
    There can be inaccuracy here. Round the value to the nearest integer number of cents first:

    Code:
    z = (double)(int)(z * 100 + 0.5);
    Ah, right. Thank you very much, it seems to work 100&#37; now.

    EDIT: I also noticed if I go back to working with the decimals and set: z = z + 0.005; it seems to work perfectly as well.
    Last edited by nate92488; 04-25-2007 at 12:36 PM.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by nate92488 View Post
    I also noticed if I go back to working with the decimals and set: z = z + 0.005; it seems to work perfectly as well.
    It only works by chance. The roundoff errors which occur here usually end up on the low side, so by adding a small value you compensate for it. But it's not a "real" solution.

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    5
    Quote Originally Posted by brewbuck View Post
    It only works by chance. The roundoff errors which occur here usually end up on the low side, so by adding a small value you compensate for it. But it's not a "real" solution.
    Alright, makes sense. Thank you for all your help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 05-13-2009, 03:25 PM
  2. Replies: 14
    Last Post: 06-28-2006, 01:58 AM
  3. Could somebody please help me with this C program
    By brett73 in forum C Programming
    Replies: 6
    Last Post: 11-25-2004, 02:19 AM
  4. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM