Change Dispenser Program Coding

SkippyThorson

macrumors 68000
Original poster
Back again, rather soon, after the past 2 easier weeks. This time, it is the infamous Change Dispenser program. It's plastered all over the web as the intro program teacher of choice, but I'm not feeling its power.

Any words of wisdom to get me to a problem solving state of mind? I've included what I've got so far, but unsure of some - in particular, static_cast<int>.

Code:
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;

double due, paid, difference;
int change, dollars, q, n, d, p;

int main ()
{
printf ("Welcome. \n");
printf ("Enter the amount due: \n");
scanf("%lf", &due);
printf ("Enter the amount paid: \n");
scanf("%lf", &paid);

double difference = paid - due;
int change = static_cast<int> (difference * 100);

int dollars = change / 100;
change = change - ( dollars * 100);
int q = change / 25;
change = change - ( q * 25);
int d = change / 10;
change = change - ( d * 10);
int n = change / 5;
change = change - ( n * 5);
int p = change / 1;
change = change - ( p * 1);

printf ("The return change is as follows. \n");
printf ("Amount of Dollars:   %.2lf \n", dollars);
printf ("Amount of Quarters:  %.2lf \n", q);
printf ("Amount of Dimes:     %.2lf \n", d);
printf ("Amount of Nickels:   %.2lf \n", n);
printf ("Amount of Pennies:   %.2lf \n", p);

return 0;
}

MorphingDragon

macrumors 603
Take some actuall coins and pretend youre taking a sale and giving change. - This is what I did in effect while making some OpenOffice Macros for work.

Analyze your thought process while doing it (Harder than it sounds) and write it down as pseudo code. (Hint I believe theres something more suitable than dividing)

notjustjay

macrumors 603
Agreed. Before you write a single line of code, figure out how to solve the problem "on paper".

Then write out an algorithm. It will look something like this:

Get the total amount due.
Get the total amount given.
The change needed = amount given - amount due
Work with the amount in pennies (dollar amount x 100)

number of dollar bills to give back = change amount divided by 100
calculate remainder after giving out that number of dollars

...remainder must be given out in smaller denominations...

etc.

You've probably already done this step, at least partially.

lloyddean

macrumors 65816
A promising start with good use of float vs int variables.

Your use of 'static_cast<int>' seems appropriate to me as it indicates you really wanted to "cast" the results of the difference between two floats to an 'int' instead of relying on an 'implicit' cast.

I would like to point out that

Code:
int change = static_cast<int> (difference * 100);
will produce a roundoff error. Try 'due' of 12.84 and 'paid' of 50.00 for instance and you'll see what I mean.

A slight adjustment will compensate:

Code:
int change = static_cast<int> (difference * 1000) / 10;

Since you are using C++ I'd like to point out the C++ standard does not have either of the header files "stdio.h" or "math.h". These are crutches many compilers provide but they are not standard and may not be available under all compilers. Instead 'cstdio' and 'cmath' are what you should be using.

Mac_Max

macrumors 6502
If you're not getting the output you were hoping for, it's because you're trying to use a format function that looks for a double and not an int (or so XCode tells me). Since you're outputting ints you really don't need to format the text anyways. I also changed the lines that remove the amount of change you've just checked for to use a modulus operator since essentially you're just looking for the remainder. , i.e. "change = change % 5;" instead of "change = change - ( n * 5);". Most sample answers to this problem should show modulus being used.

Code:
#include <iostream>
using namespace std;

double due, paid, difference;
int change, dollars, q, n, d, p;

int main ()
{
cout << "Welcome. \n";
cout << "Enter the amount due: ";
cin >> due;
cout << "Enter the amount paid: ";
cin >> paid;

double difference = paid - due;
int change = static_cast<int> (difference * 100);

int dollars = change / 100;
change = change % 100;
int q = change / 25;
change = change % 25;
int d = change / 10;
change = change % 10;
int n = change / 5;
change = change % 5;
int p = change / 1;
change = change % 1;

printf ("The return change is as follows. \n");
cout << "Amount of Dollars: " << dollars << endl;
cout << "Amount of Quarters: " << q << endl;
cout << "Amount of Dimes: " << d << endl;
cout << "Amount of Nickles: " << n << endl;
cout << "Amount of Pennies: " << p << endl;

return 0;
}
I changed everything to use cout/cin as well since those are what I'm most used to.

lloyddean

macrumors 65816
Code:
printf ("The return change is as follows. \n");
I changed everything to use cout/cin as well since those are what I'm most used to.
Oops, look there you missed one!

SkippyThorson might I ask what class you're taking and what's been covered so far. The reason being it will allow us not to confuse you by making suggestions with things that haven't be introduced in class yet.

SkippyThorson

macrumors 68000
Original poster
Dragon and Jay, I've gone through that a couple times. It's the applying it to lines of code on a computer screen that seems to be the issue. I know what I want done, and Jay, I that very similarly to how you explained it, but it's a bit like trying to translate it into Japanese that I've only taken an intro in. It's kind of awkward to go from A to B - the transition I mean.

Lloyd, I see what you have going on there. I'll take a further look into that. As for stdio.h and math.h... Well, our instructor has been telling us from the first week that those were things we mustn't forget to add because of necessity. I don't want to go against her, so I'll continue to keep them in. I would actually like to learn her reasoning now though.
-- I'll try to sum it all up in the very near future. It hasn't been a lot, but what has happened has been important, so I don't want to skip around.

Max, I have to look into your solution a little more. I hadn't considered working through it that way.

notjustjay

macrumors 603
Dragon and Jay, I've gone through that a couple times. It's the applying it to lines of code on a computer screen that seems to be the issue. I know what I want done, and Jay, I that very similarly to how you explained it, but it's a bit like trying to translate it into Japanese that I've only taken an intro in. It's kind of awkward to go from A to B - the transition I mean.
That's a good place to be in. The point I was trying to get across was that you need to know exactly what you want done, then you just have to figure out how to translate the steps into code. That's a lot easier than sitting down at a text editor and trying to figure out both what you actually want done AND how to do it using the programming language.

As I said in an earlier thread (I think it was yours), too many programming teachers focus on how to write code, without actually training you to think in terms of algorithms. It's like sitting down to write a novel, but not having any kind of plot in mind. It's possible to make things up as you go, but I think a good writing class would teach you to put together a detailed outline before you start writing a single word of your manuscript.

Anyway, it sounds like I'm preaching to the choir. lloyddean

macrumors 65816
As for stdio.h and math.h... Well, our instructor has been telling us from the first week that those were things we mustn't forget to add because of necessity. I don't want to go against her, so I'll continue to keep them in. I would actually like to learn her reasoning now though.
Read it for yourself on page 319 of the standards document "iso14882-C++98.pdf"

SkippyThorson

macrumors 68000
Original poster
I have learned, in a nutshell:
What characters are what, and what they do (specific functions, not char) formats, basic math, switch / if / elseif statements, for / while / do...while loops, Palindromes, and now we're moving through arrays. If any of that helps. Now, I'm not too sure I know all there is to know about modulo operation other than it differs from division by leaving you the remainder; 8 % 4 = 0, 7 % 3 = 1.

My results for all of them are the %.2lf; 0.00 with 2 after the decimal. Does that have anything to do with my use of math, or is it something I just wrote wrong?

What it's doing now is taking the entered amount, dividing it by the amount designated by the cash value I'm trying to get at the time, and then taking the remainder that comes after the value is taken, and plugs it in for the values in decreasing order.

I get it, I don't think it gets me. lloyddean

macrumors 65816
Code:
printf ("Amount of Dollars:   %.2lf \n", dollars);
Lets ask why, given that 'dollars' is an 'int', are you using ANY 'float' formatting at all.

The next question is why are you using 'printf' which requires YOU to specify the data type being printed when, since you're using C++, 'cout' will do the correct thing for the data type it is outputting.

As an aside I think your current instructor knows 'C', doesn't know 'C++', and is a chapter ahead of you in learning it herself.

SkippyThorson

macrumors 68000
Original poster
Code:
printf ("Amount of Dollars:   %.2lf \n", dollars);
Lets ask why, given that 'dollars' is an 'int', are you using ANY 'float' formatting at all.

The next question is why are you using 'printf' which requires YOU to specify the data type being printed when, since you're using C++, 'cout' will do the correct thing for the data type it is outputting.

As an aside I think your current instructor knows 'C', doesn't know 'C++', and is a chapter ahead of you in learning it herself. I could hug you right now. The answer to all of those questions is simple; those are what she taught us and told us to use from day one, and the only way she'll accept our work.

Before I even started the class and went over to a friend's house, he showed me C vs C++. When we began, I was thrilled to have already been opened up to "cin" and "cout" and things like "ceiling / floor", but to this day, she has never once uttered any of those, and those were about the only things I knew going in to the class. I didn't even have Xcode, so I figured "printf" and "scanf" were just it. A that's that acceptance thing.

As for your first question, we were given a handout that included that line in it; obviously which I changed to "Amount of Dollars / dollars". The what-was-there-before-dollars was declared as an int. Again, I figured that was just accepted, because that's what I was shown. Wonderful, I'm basically learning a language as useful in todays world as Latin.

Code:
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;

// Variables double and integer.
double due, paid, difference;
int change, dollars, q, n, d, p;

int main ()
{
// Input where the user enters the amounts due and paid.
printf ("Welcome. \n");
printf ("Enter the amount due: \n");
scanf("%lf", &due);
printf ("Enter the amount paid: \n");
scanf("%lf", &paid);

// The amount difference is used to calculate a new variable, called change.
difference = paid - due;
change = static_cast<int> ((difference * 1000) / 10);

// Change is calculated by the difference, and the amounts
// of various money back is displayed below after calculation.
// The amounts are taken by modulo division, and the remianders
// create the decreasing change equations in order.
// The .00001 for the penny prevents a rounding error.
dollars = (change / 100);
change = (change % 100);
q = (change / 25);
change = (change % 25);
d = (change / 10);
change = (change % 10);
n = (change / 5);
change = (change % 5);
p = ((change + .00001) / 1);

// Output shows the numerical amounts of what change should be given back.
printf ("The return change is as follows. \n");
printf ("Amount of Dollars:   %x \n", dollars);
printf ("Amount of Quarters:  %x \n", q);
printf ("Amount of Dimes:     %x \n", d);
printf ("Amount of Nickels:   %x \n", n);
printf ("Amount of Pennies:   %x \n", p);

// End.
return 0;
}
At any rate, I have arrived at this point, still going. I'm now getting the change, it's just the wrong amounts. Still truckin'. It works when you enter say...
3.75 due / 10.00 paid
...or...
12.84 due / 20.00 paid
...but when I enter...
12.84 due / 50.00 paid
...the result is 25 dollars, 1 dime, 1 nickel, and 1 penny, which is 25.16, and 12.84 + 25.16 =/= 50.

-----

...and compiling it in Terminal reveals errors that Xcode does not. Why is that? Does Xcode just not take them into account?

lloyddean

macrumors 65816
Perhaps you can explain to why you're doing each of these lines:

Code:
dollars = (change / 100);
change = (change % 100);
and how it affects 'change' ?

Clue: you had it correct in your first post!

SkippyThorson

macrumors 68000
Original poster
Perhaps you can explain to why you're doing each of these lines:

Code:
dollars = (change / 100);
change = (change % 100);
and how it affects 'change' ?

Clue: you had it correct in your first post!
Max mentioned it here, and it seems to make sense. It takes the variable change, and divides it by 100, which equals dollars. It then takes the remainder of change, which reduces it to be used in the next equation. Effectively, aren't those the same things? It does give me the same results.

lloyddean

macrumors 65816
Max mentioned it here, and it seems to make sense. It takes the variable change, and divides it by 100, which equals dollars. It then takes whatever is left over from change, and reduces it to be used in the next equation. Effectively, aren't those the same things?
Write it out using numbers instead of the variable names and post it.

SkippyThorson

macrumors 68000
Original poster
Write it out using numbers instead of the variable names and post it.
Using 3.75 due and 10.00 paid:

Code:
dollars = change / 100;
change = change - ( dollars * 100);
7 = 700 / 100; //The 700 is 7.00 from the first portion of 'difference'.
0 = 700 - (7 * 100); //700 from 'change' and 7 from 'Dollars' = 0.

Code:
dollars = (change / 100);
change = (change % 100);
7 = 700 / 100; //The 700 is 7.00 from the first portion of 'difference'.
0 = 700 % 100; //The remainder of 700 / 100 = 0.

Right? lloyddean

macrumors 65816
You're correct.

I misread your post above, you are correct and I've been misleading you the last couple of post due to fatigue on my part.

Apologies.

So then you lost me with:

...and compiling it in Terminal reveals errors that Xcode does not. Why is that? Does Xcode just not take them into account?

SkippyThorson

macrumors 68000
Original poster
You're correct.

I misread your post above, you are correct and I've been misleading you the last couple of post due to fatigue on my part.

Apologies.

So then you lost me with:
SABOTEUR! It's fine, really - I realized you've just forced me to comment in the way I probably should have all along.

In Xcode, my program succeeds, and I can execute it just fine. However, when I compile the program in terminal using 'gcc change.c', I get:

Code:
change.c:25:20: error: iostream: No such file or directory
change.c:26: error: syntax error before ‘namespace’
change.c:26: warning: data definition has no type or storage class
change.c: In function ‘main’:
change.c:43: error: ‘static_cast’ undeclared (first use in this function)
change.c:43: error: (Each undeclared identifier is reported only once
change.c:43: error: for each function it appears in.)
change.c:43: error: syntax error before ‘int’
I put the latest rendition of my program in post #12 just above here. Simply removing iostream solves that one, but I don't necessarily understand the rest. What do they mean?

I'm gonna go Google "Syntax Error" and catch some sleep. I'll let you do the same instead of taxing you further.

lee1210

macrumors 68040
You're (sort of, as much as you're allowed) using c++, not C. Name your file .cpp and compile with g++ instead of gcc.

For pennies, no need to do odd rounding. If you calculated change right, its value at the end should be the number of pennies needed.

I'd get your values into ints as soon as possible. Maybe even before you get your difference. Floating point is inexact, integer math is completely precise.

Multiplying by 1000 then dividing by 10 seems the same to me as multiplying by 100. Is there a reason you've complicated it?

It's probably not required here, but what happens if the amount paid is less than the amount due? What if more than two digits appear after the decimal point?

-Lee

chown33

Moderator
Staff member
Wonderful, I'm basically learning a language as useful in todays world as Latin.
C is somewhat more useful than Latin. At least in programming tasks.

Code:
printf ("Amount of Dollars:   %x \n", dollars);
printf ("Amount of Quarters:  %x \n", q);
printf ("Amount of Dimes:     %x \n", d);
printf ("Amount of Nickels:   %x \n", n);
printf ("Amount of Pennies:   %x \n", p);
I recommend learning to read man pages. This lets you read the primary reference, rather than just guessing or taking someone's opinion at face value.

There is a simple yet effective interface to man pages under Xcode's Help menu.

Also see this:
http://bruji.com/bwana/index.html

Start by referring to the printf man page. I recommend opening the man page now, and finding the section that describes the meaning of the print-format characters.

http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man3/printf.3.html

The %x print-format will print a value in hex. As in hexadecimal, base-16. I find it hard to believe that's what you want or need. Hex and decimal (base-10) coincide until the numeric value exceeds 9. That won't appear in your result unless there is an amount of change in excess of \$9.99....

At any rate, I have arrived at this point, still going. I'm now getting the change, it's just the wrong amounts. Still truckin'. It works when you enter say...
3.75 due / 10.00 paid
...or...
12.84 due / 20.00 paid
...but when I enter...
12.84 due / 50.00 paid
...the result is 25 dollars, 1 dime, 1 nickel, and 1 penny, which is 25.16, and 12.84 + 25.16 =/= 50.
... like that.

SkippyThorson

macrumors 68000
Original poster
You're (sort of, as much as you're allowed) using c++, not C. Name your file .cpp and compile with g++ instead of gcc.

For pennies, no need to do odd rounding. If you calculated change right, its value at the end should be the number of pennies needed.

I'd get your values into ints as soon as possible. Maybe even before you get your difference. Floating point is inexact, integer math is completely precise.

Multiplying by 1000 then dividing by 10 seems the same to me as multiplying by 100. Is there a reason you've complicated it?

It's probably not required here, but what happens if the amount paid is less than the amount due? What if more than two digits appear after the decimal point?

-Lee
We never learned about the differences between gcc and g++. I'll have to read up on that.

Lloyd mentioned a rounding error caused by just using 100, and to suggested switching it to that, and while it does the same thing, I guess being on the safe side doesn't hurt.

If paid is less than due, I have taken into consideration if / else statements, and stuck in an error that says so.

C is somewhat more useful than Latin. At least in programming tasks.

I recommend learning to read man pages. This lets you read the primary reference, rather than just guessing or taking someone's opinion at face value.

There is a simple yet effective interface to man pages under Xcode's Help menu.

Also see this:
http://bruji.com/bwana/index.html

Start by referring to the printf man page. I recommend opening the man page now, and finding the section that describes the meaning of the print-format characters.

http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man3/printf.3.html

The %x print-format will print a value in hex. As in hexadecimal, base-16. I find it hard to believe that's what you want or need. Hex and decimal (base-10) coincide until the numeric value exceeds 9. That won't appear in your result unless there is an amount of change in excess of \$9.99....

... like that.
Good call on that one - I read up on it, and switched it to %i, for decimal signed integers.

I saw my instructor about it, and she also helped me out with the first 'if' portion including prevention of the rounding error. The only thing she didn't like was the 'static_cast<int>', and so she removed it.

After a bit more toggling with it - it works right, does what it should, when it should, and it looks good now! I hope... Maybe... Code:
#include <stdio.h>
#include <math.h>

// Variables double and integer.
double due, paid, difference;
int change, dollars, q, n, d, p;
int main (void)
{
// Input where the user enters the amounts due and paid.
printf ("Welcome. \n");
printf ("Enter the amount due: \n");
scanf("%lf", &due);
printf ("Enter the amount paid: \n");
scanf("%lf", &paid);

// If paid is greater than due, the program executes normally.
if (paid > due)
{
// The amount difference is used to calculate a new variable, called change.
difference = paid - due;
difference = difference + 0.00001;
printf( "The difference is: %8.2lf \n", difference);
difference = difference * 100;
change = (int) (difference);
printf( "The value of change is: %d \n\n", change);

// Change is calculated by the difference, and the amounts
// of various money back is displayed below after calculation.
// The amounts are taken by modulo division, and the remianders
// create the decreasing change equations in order.
dollars = change / 100;
change = change % 100;
q = change / 25;
change = change % 25;
d = change / 10;
change = change % 10;
n = change / 5;
change = change % 5;
p = change;

// Output shows the numerical amounts of what change should be given back.
printf ("The return change is as follows. \n");
printf ("Amount of Dollars:   %i \n", dollars);
printf ("Amount of Quarters:  %i \n", q);
printf ("Amount of Dimes:     %i \n", d);
printf ("Amount of Nickels:   %i \n", n);
printf ("Amount of Pennies:   %i \n", p);
}

// If paid is less than due, an error occurs.
else
{
printf ("Error: The amount paid must be more than the amount due. \n");
}

// End.
return 0;
}

lloyddean

macrumors 65816
Great 'C' language implementation, but I thought you were taking doing 'C++' based programming?

Again what is the title of the class you're taking and where?

lee1210

macrumors 68040
I would still insist that you get the two values as integer's before you do the difference. Doing floating point subtraction, rounding, etc. is no good. Multiply times 100, cast to an int, then get your difference. I guess you could add .00001 or whatever to each of these to try to account for the imprecision of the floating point values, but i don't think you should need it.

What would be best would be to read two ints separated by a ., then multiply the first by 100, add the second, and you have your value in cents without any messy floating point estimation at all.

-Lee

SkippyThorson

macrumors 68000
Original poster
Great 'C' language implementation, but I thought you were taking doing 'C++' based programming?

Again what is the title of the class you're taking and where?
The class is called Computing Fundamentals, at SUNY Institute of Technology. The text is Problem Solving and Problem Design in C, but we're actually learning a bit of both C and C++, depending on how they relate at the time, so it's a bit confusing. All programs however should be written in standard C.

I would still insist that you get the two values as integer's before you do the difference. Doing floating point subtraction, rounding, etc. is no good. Multiply times 100, cast to an int, then get your difference. I guess you could add .00001 or whatever to each of these to try to account for the imprecision of the floating point values, but i don't think you should need it.

What would be best would be to read two ints separated by a ., then multiply the first by 100, add the second, and you have your value in cents without any messy floating point estimation at all.

-Lee
Paid and Due? I assume you don't mean insert into the problem --
Code:
paid = int paid;
due = int due;
-- but that I should declare them as int from the beginning?

Interesting solution you describe. We haven't learned anything like that. It seems like your method saves time, space and in the process eliminates the need for the variable 'difference'. Let me see if I understand you right (I'm not doing this in XCode, just off the top of my head, sorry if I'm / it's incorrect) --

Code:
int due, paid, change, dollars, q, n, d, p;
int main (void)
{
printf ("Welcome. \n");
printf ("Enter the amounts due and paid: \n");
scanf("%lf. %lf", &due, &paid);

if (paid > due)
{
due = due * 100
change = due + paid
printf( "The value of change is: %d \n\n", change);

lloyddean

macrumors 65816
The class is called Computing Fundamentals, at SUNY Institute of Technology. The text is Problem Solving and Problem Design in C, but we're actually learning a bit of both C and C++, depending on how they relate at the time, so it's a bit confusing. All programs however should be written in standard C.
My apologies again.

With your first post code beginning with

Code:
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
and the use of 'static_cast<int>' I made the assumption that you were learning to program around C++.

Might I suggest that in the future that you start you topics with some summary of the above information. It'll help determine how we can best assist you.