0

I have a problem in my code and i can't find the answer for it. I only can use if and else and can't use other classes for an example Math.

The code save a value and try to divide in euro coins. If i enter 4,31 the result is 2x2e + 1x20c + 1x1c and this is ok but if i enter the value 1,20 the result is 1e + 1x10c + 1x5c + 2x2c + 1x1c but the right result is 1e + 1x20c. I had to add 0.001 in the 1cent coin because if i don't i'll not get a print for it. Adding this is wrong too.

If somebody could help me i would be very grateful. Regards.

Code:

import java.util.Scanner;

public class Coins {

    public static void main(String[] args){
        Scanner in= new Scanner(System.in);

        int e2 = 0, e1 = 0,c50 = 0,  c20=0,c10 = 0,c5 = 0,c2 = 0,c1;
        double v;

        System.out.println("Quantia em euros: ");
        v = in.nextDouble();

        e2 = (int)v/2;
        v=v-e2*2;

        e1=(int)v;
        v=(v-e1)*100;

        c50=(int)v/50;
        v=v-c50*50;

        c20=(int)v/20;
        v=v-c20*20;

        c10=(int)v/10;
        v=v-c10*10;

        c5=(int)v/5;
        v=v-c5*5;

        c2=(int)v/2;
        v=v-c2*2;

        c1=(int)(v+0.001);

        if(e2!=0)System.out.print(e2+"X2Eur ");
        if(e2!=0&&!(e1==0&&c50==0&&c20==0&&c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
        if(e1!=0)System.out.print(e1+"X1Eur ");   
        if(e1!=0&&!(c50==0&&c20==0&&c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
        if(c50!=0)System.out.print(c50+"X50c ");  
        if(c50!=0&&!(c20==0&&c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
        if(c20!=0)System.out.print(c20+"X20c ");  
        if(c20!=0&&!(c10==0&&c5==0&&c2==0&&c1==0))System.out.print("+ ");
        if(c10!=0)System.out.print(c10+"X10c ");  
        if(c10!=0&&!((c5==0&&c2==0&&c1==0)))System.out.print("+ ");
        if(c5!=0)System.out.print(c5+"X5c ");     
        if(c5!=0&&!(c2==0&&c1==0))System.out.print("+ ");
        if(c2!=0)System.out.print(c2+"X2c ");    
        if(c2!=0&&!(c1==0))System.out.print("+ ");
        if(c1!=0)System.out.print(c1+"X1c");
    }
}
beresfordt
  • 5,088
  • 10
  • 35
  • 43
BFR
  • 3
  • 2
  • 5
    Congratulations - You've discovered why using a `double` to store an amount of money is a terrible idea! (Because it stores something like `4.30999999999999995478678527893476230741`) – user253751 Mar 23 '15 at 23:52
  • See [this question](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency) for details – beresfordt Mar 24 '15 at 00:05

3 Answers3

0

These are rounding errors by Java, they can always occur when using floats. In your case you keep editting the same value so the error gets bigger and bigger.

Use

System.out.println("Quantia em euros: ");
v = 1.20;
int cents = (int)(v*100);
e2 = cents/200;
cents = cents%200;

e1=cents / 100;
cents = cents % 100;

c50=cents/50;
cents = cents%50;

c20=(int)cents/20;
cents =  cents %20;

c10=(int)cents/10;
cents = cents%10;

c5=(int)cents/5;
cents = cents % 5;

c2=(int)cents/2;


c1=cents%2;

Because rounding errors don't occur on ints.

Soronbe
  • 906
  • 5
  • 12
0

first of all: if you store a value in a double-variable, always consider that double is a bit imprecise, i'd use cents instead (simply remove the comma and parse to int).

for the implementation itself: optimize the whole thing using arrays.

final int[] coin_values = new int[]{
     200 , 100 , 50 , 20 , 10 , 5 , 2 , 1};
final String[] coin_names = new String[]{
     "2€" , "1€" , "50ct" , "20ct" , "10ct" , "5ct" , "2ct" , "1ct"};

String input = in.next();
String[] temp = input.split(".");
input = temp[0] + temp[1];
int value = Integer.parseInt(input);

int[] coins = new int[coin_values.length];

for(int i = 0 ; i < coins.length ; i++){
     coins[i] = value / coin_values[i];
     value %= coin_values[i];

     if(coins[i] != 0)
          System.out.print(coins[i] + " " + coin_names[i] + " + ");
}
  • this would be fine but i can only use if and else statements – BFR Mar 24 '15 at 00:17
  • @BFR well Paul completely rewrote your code for some reason, but you don't need to completely rewrite it, just do what he said in the first paragraph (use cents instead of euros, so you can store it in an int) – user253751 Mar 24 '15 at 02:25
0

In Java always use java.math.BigDecimal for monetary amounts. You won't get strange rounding behaviour that you can't control.

Persixty
  • 8,165
  • 2
  • 13
  • 35