0

I have written a C++ program (supposed to be a money counter), I'm having some trouble with my code, I need the decimals to show up. I use cout instead of printf if that matters.

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

int main() {
    // Strings and Integers
    int dollars;
    int pennies;
    int nickles;
    int quarters;
    int halfDollars;
    int dimes;
    int fiveBill;
    int tenBill;
    int twentyBill;
    int fiftyBill;
    int hundredBill;

    // Coin/Bill Amounts
    int penny = 0.01;
    int dollar = 1.00;
    int nickle = 0.05;
    int quarter = 0.25;
    int halfDollar = 0.50;
    int dime = 0.10;
    int five = 5.00;
    int ten = 10.00;
    int twenty = 20.00;
    int fifty = 50.00;
    int hundred = 100.00;

    // Enter Amount
    cout << "Count your money!\n\n" << endl << "Hundred Dollar Bills: ";
    cin >> hundredBill;
    cout << "\nFifty Dollar Bills: ";
    cin >> fiftyBill;
    cout << "\nTwenty Dollar Bills: ";
    cin >> twentyBill;
    cout << "\nTen Dollar Bills: ";
    cin >> tenBill;
    cout << "\nFive Dollar Bills: ";
    cin >> fiveBill;
    cout << "\nOne Dollar Bills: ";
    cin >> dollars;
    cout << "\nHalf-Dollars: ";
    cin >> halfDollars;
    cout << "\nQuaters: ";
    cin >> quarters;
    cout << "\nDimes: ";
    cin >> dimes;
    cout << "\nNickles: ";
    cin >> nickles;
    cout << "\nPennies: ";
    cin >> pennies;

    // Add Together
    cout << (hundred * hundredBill) + (fifty * fiftyBill) + (twenty *    twentyBill)  + (ten * tenBill) + (five * fiveBill) + (dollars * dollar) +   (halfDollar * halfDollars) + (quarter * quarters) + (dime * dimes) + (nickle *     nickles)   + (penny * pennies);
    system("PAUSE");

    return 0;
}
Aconcagua
  • 24,880
  • 4
  • 34
  • 59

4 Answers4

2

Your problem:

int penny = 0.01;

penny is an int, the name is short for 'integral value'. 0.01 is of type double. If you assign a double (either as literal or from another variable) to any form of int (int, long int, short int, ...), only the integral part is assigned and the decimals are dropped (simply dropped, no rounding occurs - no matter how close the value is to the next greater integral one).

So penny actually holds only 0. Alike the other variables, dollar is 1, nickle again 0, ...

You have now two choices. Either, you convert all numbers to double, or you do a little trick by assigning all values in cents:

int penny = 1;
int dollar = 100;

This is what I would prefer. Then only when it comes to outputting you would do appropriate formatting:

printf("the value of my variable is %d.%.2d $\n", value / 100, value % 100);

Edit:

As many prefer outputting via std::cout and this gets rather a hassle, a way to do it conveniently would be the following:

class Formatter
{
    int value;
    friend std::ostream& operator<<(std::ostream& s, Formatter f);
public:
    Formatter(int value)
            : value(value)
    {
    }
};
typedef Formatter F, M;

std::ostream& operator<<(std::ostream& s, Formatter f)
{
    char c = s.fill();
    return s << f.value / 100 << '.'
        << std::setfill('0') << std::setw(2) << f.value % 100
        << std::setfill(c); // restore previous fill character!
}

Typedef is not necessary, of course, just to illustrate other names – select any one that seems most appropriate to you (F: Formatter, M: Money, D: Dollar, ...). Usage then:

std::cout << F(penny) << std::endl;
Aconcagua
  • 24,880
  • 4
  • 34
  • 59
  • Smart solution actually, except the stream may misbehave for further outputs. – Paul Stelian Jul 05 '16 at 08:10
  • 1
    @PaulStelian Thanks for the hint - while the effects of setw are reset by the next operator<< (see [here](http://en.cppreference.com/w/cpp/io/manip/setw)), I oversaw that those of setfill are not... Edited appropriately. – Aconcagua Jul 05 '16 at 08:33
1

As stated, the problem is that you are trying to assign a decimal value to an integer variable.

What occurs, is that your input (in the case of decimal values) can either be interpreted as a double or a float -type variable by the compiler. During the assignment of the given input however, int or fully, an integer, can only hold a value without a fractional component. Compiler takes note of this, and simply narrows your given input into a value the int variable can hold. The compiler isn't interested about anything after the decimal point, and simply discards the rest.

Thus,

int a = 3.5 // int can't hold the decimal 0.5, narrows into 3
int b = 3 // int can hold this, no narrowing
double d = 3.5 // double can hold this, no narrowing
float f = 3.5 // float can hold this, no narrowing

A good way would be to replace all your integer variables with the type double. In this simple a program, you shouldn't have the need to use printf to format the input.

And in the case you are wondering, why would I want to use double instead of float.

Here is some additional information:

https://softwareengineering.stackexchange.com/questions/188721/when-do-you-use-float-and-when-do-you-use-double

Should I use double or float?

Community
  • 1
  • 1
Jani
  • 11
  • 1
  • 2
  • While I proposed usage of double as one alterntive, too, there also are some drawbacks: floating point arithmetic is more expensive, there are issues with rounding, equality comparison must be done as abs(difference) < someThreshold), ... – Aconcagua Jul 05 '16 at 07:25
  • That is indeed the case and I fully agree with you. However, I believe that in case of a simple program such as this, we should not consider ourselves with the performance issues of floating point arithmetics. – Jani Jul 05 '16 at 08:44
  • Sure, performance is only a side effect and should not be considered for the decision. But you might like this one: `double penny = 0.01; double nickle = 0.05; std::cout << (2*penny + 3*penny == nickle) << std::endl;`. In such simple programs, I would prefer to be able to use operator==... – Aconcagua Jul 05 '16 at 10:21
  • Well, that is one of the drawbacks as you said. I got to agree that we are passing the simplicity if we want implement a function that takes care of the equality comparison in a tolerable sense. – Jani Jul 05 '16 at 14:03
1

If you want to keep integers, cast the result to a float or double. Then set precision to 2 digits and fixed format.

#include <iostream>
#include <iomanip>

...

float total = (float) ((hundred * hundredBill) + (fifty * fiftyBill) + (twenty *    twentyBill) + (ten * tenBill) + (five * fiveBill) + (dollars * dollar) + (halfDollar * halfDollars) + (quarter * quarters) + (dime * dimes) + (nickle * nickles) + (penny * pennies));
cout << std::setprecision(2) << std::fixed << total << endl;
Marc
  • 856
  • 1
  • 8
  • 20
  • 1
    Good hint on formatting (precision, fixed). That's what the other 'floating point' answers were lacking so far... – Aconcagua Jul 05 '16 at 07:55
0

I use "cout" instead of "printf" if that matters.

No it won't matter with whatever output you were expecting.

Use all the variables you want to manipulate w.r.t. decimals as 'double' data type.

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
Vineet Kumar
  • 86
  • 1
  • 7
  • 2
    `printf` causes in many cases a lot of less hassle, compare `"%.2d", value` to `<< setw(2) << setfill('0') << value`. That's probably the reason it is still alive (and very alive...) in C++. Admitted, on the other hand, cout has great advantage if working with typedef's which you don't know the exact type - or the latter might change... – Aconcagua Jul 05 '16 at 07:17
  • @Aconcagua completely agree! – Vineet Kumar Jul 05 '16 at 07:31