I'm new to the programming world and C++ is already losing me. I had these lines in my program
pennies=(amount-nickels*.05)/.01;
amount is a double
, while and nickels are int
.
The program returns the right value when pennies is a double
but things are a little off (off by 1 most of the time) whenever pennies is an int
.
Why is this happening?
This is happening because the value is truncated thus losing the decimal precision.
For integers:
int i;
i = 1.1 //stores 1 in i
i = 1.2 //stores 1 in i
i = 1.3 //stores 1 in i
i = 1.4 //stores 1 in i
i = 1.5 //stores 1 in i
i = 1.6 //stores 1 in i
i = 1.7 //stores 1 in i
i = 1.8 //stores 1 in i
i = 1.9 //stores 1 in i
i = 1.999999 //stores 1 in i
I would suggest you to change your expression to:
pennies=amount*100-nickels*5;
As others have pointed out, the problem is because 0.1
and
0.05
don't have an exact representations in machine floating
point. The simplest solution here is to simply round the
results, instead of truncating:
pennies = round( (amount - nickels * 0.05) / 0.01 );
A better solution in this particular case (where you are dealing with coins) is simply to use integers everywhere, and do everything in terms of cents, rather than dollars. This stops working (or requires some very complex programming) very quickly however: even things like calculating VAT or sales tax cause problems. For such cases, there are two possible solutions:
Continue using double
, rounding as necessary. This is the
simplest and most general solution. Be aware, however, that
when using it, rounding is done on binary values, and it may
in some cases differ from what you would get with rounding
decimal values. The difference should be small enough that it
won't matter for every day use, but most countries have laws
specifying how such values must be rounded, and those rounding
rules are always specified in decimal. Which means that this
solution cannot be used in cases where legal requirements hold
(e.g calculating sales tax, corporate bookkeeping, etc.).
Use some sort of decimal class. There are a number available on the network. This will result in slower execution times. (Typically, who cares. You'll get the results in 100 microseconds, rather than 10. But there are exceptions; e.g. when doing Monte Carlo simulations.)
Also, you must be aware when large values are involved. For
your personal finances, it's almost certainly irrelevant, but
int
does have a maximum value, and there is a point where
double
can no longer represent integer values correctly.
Of course, if this is just an exercise to help in learning C++,
just use round
or integers, and don't worry too much about the
rest.
And as for your comment "C++ is already losing me": this has nothing to do with C++ per se. You'd encounter exactly the same issues in (almost) any programming language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With