[Newbie] Type conversion - Loss of accuracy

P

PercyP

Hi,

I'm writing a program that will take input of an amount of money (In
GBP/pounds, £) and output the lowest denomination of notes/coins for that
amount. These are £50, £20, £10, £5, £2, £1, 50p, 20p, 10p, 5p, 2p, 1p.
So, for example, If £35.42 was input, the program will tell you that you
need one £20, one £10, one £5, two 20p and one 2p.

I am using type conversion to convert the float that is input, to integers
to show the number of each denomination (As I don't want to be told you need
2.0 notes, for example). My program works fine for even inputs (£1.78,
£4.50, £50.42, etc.) but if you enter an odd number, it somehow looses part
of it. So if I input £1.79, it would be used as if it were
£1.789999999999... So not quite £1.79. This is a pain when you want the
exact amount as you are displaying the number of coins/notes needed.

I have pasted my code below. Would someone please be able to tell me the
reason my code is interpreting odd numbers as 'not quite' the value that
they are? And maybe suggest on how to fix it, incase I need to use the idea
for more complex programs in the future. An obvious solution, which works,
is to add something like 0.005 to the number input. That way it is slightly
over and thus will give you whole amounts of coins/notes, but not too far
over to ever output too many coins/notes. However, this is not the most
efficient way to do what I want, and would prefer to use the correct way.

Thanks,

Percy

/** CODE BEGIN */

/** This program will take an amount in Pounds from the user and output
the amount of change for the smallest denomination of each coin or note
*/

public class MoneyMoneyMoney2
{
public static void main(String[]args)
{
//Declare variables where c stands for 'change'
int cFiftyPounds, cTwentyPounds, cTenPounds, cFivePounds, cTwoPounds,
cOnePound,
cFiftyPence, cTwentyPence, cTenPence, cFivePence, cTwoPence, cOnePence;

//Currency input for user's inital amount. amountStore to keep track of
change.
float currencyInput, amountStore;

//Get input from user. KBInput is a simple class that reads the user's
input.
System.out.print("Please input an amount in Pounds Sterling: £");
currencyInput = KBInput.readFloat();

//Calculate number of £50 notes
cFiftyPounds = (int)currencyInput / 50;
amountStore = currencyInput - cFiftyPounds * 50;

//Calculate number of £20 notes
cTwentyPounds = (int)amountStore/20;
amountStore = amountStore - cTwentyPounds * 20;

//Calculate number of £10 notes
cTenPounds = (int)amountStore/10;
amountStore = amountStore - cTenPounds * 10;

//Calculate number of £5 notes
cFivePounds = (int)amountStore/5;
amountStore = amountStore - cFivePounds * 5;

//Calculate number of £2 coins
cTwoPounds = (int)amountStore/2;
amountStore = amountStore - cTwoPounds * 2;

//Calculate number of £1 coins
cOnePound = (int)amountStore/1;
amountStore = amountStore - cOnePound * 1;

//Calculate number of 50p coins
cFiftyPence = (int)(amountStore/0.5F);
amountStore = amountStore - cFiftyPence * 0.5F;

//Calculate number of 20p coins
cTwentyPence = (int)(amountStore/0.2F);
amountStore = amountStore - cTwentyPence * 0.2F;

//Calculate number of 10p coins
cTenPence = (int)(amountStore/0.1F);
amountStore = amountStore - cTenPence * 0.1F;

//Calculate number of 5p coins
cFivePence = (int)(amountStore/0.05F);
amountStore = amountStore - cFivePence * 0.05F;

//Calculate number of 2p coins
cTwoPence = (int)(amountStore/0.02F);
amountStore = amountStore - cTwoPence * 0.02F;

//Calculate number of 1p coins
cOnePence = (int)(amountStore/0.01F);
amountStore = amountStore - cOnePence * 0.01F;

//Output to user
System.out.println("Number of £50 notes: " + cFiftyPounds);
System.out.println("Number of £20 notes: " + cTwentyPounds);
System.out.println("Number of £10 notes: " + cTenPounds);
System.out.println("Number of £5 notes: " + cFivePounds);
System.out.println("Number of £2 coins: " + cTwoPounds);
System.out.println("Number of £1 coins: " + cOnePound);
System.out.println("Number of 50p coins: " + cFiftyPence);
System.out.println("Number of 20p coins: " + cTwentyPence);
System.out.println("Number of 10p coins: " + cTenPence);
System.out.println("Number of 5p coins: " + cFivePence);
System.out.println("Number of 2p coins: " + cTwoPence);
System.out.println("Number of 1p coins: " + cOnePence);

//Show the amount that is remaining. Should be 0.0.
System.out.println("New amount: " + amountStore);
}
}

/** CODE END */
 
T

Tim Ward

I'm writing a program that will take input of an amount of money (In
GBP/pounds, £) and output the lowest denomination of notes/coins for that
amount. These are £50, £20, £10, £5, £2, £1, 50p, 20p, 10p, 5p, 2p, 1p.
So, for example, If £35.42 was input, the program will tell you that you
need one £20, one £10, one £5, two 20p and one 2p.

I am using type conversion to convert the float that is input ...

Don't using floating point for money. Use an integer number of pence.
 
T

Thomas Weidenfeller

PercyP said:
I am using type conversion to convert the float that is input, to integers
to show the number of each denomination (As I don't want to be told you need
2.0 notes, for example). My program works fine for even inputs (£1.78,
£4.50, £50.42, etc.) but if you enter an odd number, it somehow looses part
of it. So if I input £1.79, it would be used as if it were
£1.789999999999... So not quite £1.79. This is a pain when you want the
exact amount as you are displaying the number of coins/notes needed.

I have pasted my code below. Would someone please be able to tell me the
reason my code is interpreting odd numbers as 'not quite' the value that
they are?

This has been discussed here again and again and again (search an
archive of this group). It is just the nature of floating point numbers
that they can't represent all numbers with exact precision. This is
typical for other programming languages, too. Use another data type for
representing your values, and please post beginner's questions to
comp.lang.java.help.

/Thomas
 
P

PercyP

Firstly sorry I posted to the wrong place, will put any further beginner
questions there.

I thought it was something to do with the language rather than my program.
I've done the program in Pascal before with practically the same algorithm
and it worked perfect, as Pascal works with significant figures rather than
floating point. I'm happy now I know the answer! :eek:)

Thanks!

Percy
 
A

arne thormodsen

PercyP said:
Firstly sorry I posted to the wrong place, will put any further beginner
questions there.

I thought it was something to do with the language rather than my program.
I've done the program in Pascal before with practically the same algorithm
and it worked perfect, as Pascal works with significant figures rather than
floating point. I'm happy now I know the answer! :eek:)

Thanks!

Percy

If it makes you feel any better (or worse?) this issue has been a
topic of conversation since at least the early days of Fortran.
Actually there are two safe ways to deal with money, one is to use
integers, the other is to use BCD arithmetic. The choice depends on
what you want to do. BCD arithmetic will allow fractional values to
be dealt with correctly (in general) so you can do things like
interest-rate calculations and get the expected result. But floating
point should never be used from money. There are some possibly
apocryphal stories of people in the early days of computing carrying
out computer fraud by calculating monetary amounts in floating point
and diverting the odd fractions to their own accounts.

--arne
 
P

PercyP

Thanks arne, that's actually quite interesting. I asked as it is one of the
exercises (Nothing major, just to help learn the language) in the module
book for my computer science degree course. The book teaches float to
integer conversion and then suggests doing the money exercise. Thus,
implying to use the float for the exercise. I guess the lecturer who wrote
the book made a bit of a bloop!

Percy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top