Velocity Reviews > Java > [Newbie] Type conversion - Loss of accuracy

# [Newbie] Type conversion - Loss of accuracy

PercyP
Guest
Posts: n/a

 10-19-2004
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: £");

//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 */

Tim Ward
Guest
Posts: n/a

 10-19-2004
> 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.

--
Tim Ward
Brett Ward Limited - www.brettward.co.uk
"PercyP" <(E-Mail Removed)> wrote in message
news:cl3c0b\$mds\$(E-Mail Removed)...

Thomas Weidenfeller
Guest
Posts: n/a

 10-19-2004
PercyP wrote:
> 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
comp.lang.java.help.

/Thomas

PercyP
Guest
Posts: n/a

 10-19-2004
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! )

Thanks!

Percy

"Thomas Weidenfeller" <(E-Mail Removed)> wrote in message
news:cl3cqi\$f6i\$(E-Mail Removed)...
> PercyP wrote:
>> 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
>
> /Thomas

arne thormodsen
Guest
Posts: n/a

 10-20-2004

"PercyP" <(E-Mail Removed)> wrote in message
news:cl3gkg\$310\$(E-Mail Removed)...
> 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! )
>
> 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

PercyP
Guest
Posts: n/a

 10-20-2004
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

"arne thormodsen" <(E-Mail Removed)> wrote in message
news:fywdd.1230\$(E-Mail Removed)...
>
> "PercyP" <(E-Mail Removed)> wrote in message
> news:cl3gkg\$310\$(E-Mail Removed)...
>> 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! )
>>
>> 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
>
>