0

I want my code to do the following things:

  • •Take in a value of currency in GBP
  • •Use 1.123 as an exchange rate to convert to Euros
  • •Inform the user how many 100,50,20,10,5 and 1 notes they will receive
  • •Give the user back the remaining balance in Euros

I have worked out the part to convert it into euros and then i just get confused. Code so far.

    int oneH;
    oneH = 0;
    Console.WriteLine("Enter the amount of money you have in GBP.");
    int gbpMON = Convert.ToInt16(Console.ReadLine());
    double euroMON = Convert.ToDouble(gbpMON * 1.123);
    Console.WriteLine("£" + gbpMON + " in Euros is €" + euroMON + ".");
    if ((euroMON - 100) <= 99);
    {
        oneH = oneH++;
    }
    
    Console.WriteLine(Convert.ToString(oneH), " x Hundreds");

So far i have only done it for the hundreds but that is how im planning on doing the rest. However when i run it, it just outputs 0 as the number of 100 notes.

  • 2
    This should help - https://www.csharp-console-examples.com/conditional/if-else-statement/coin-change-problem-in-c/ – stuartd Sep 30 '20 at 15:56
  • You are going the wrong way with if statement for this code. You want a loop over an array of bill size. Then to know how many you want a division with a `Math.Floor` and reducing the total amount is required. – Franck Sep 30 '20 at 15:56
  • First thing to do when working with money values is to use the _decimal_ type. – Steve Sep 30 '20 at 15:56
  • @Steve On what do you base yourself on to say that. I have yet to find case where decimal was useful in monetary related work. You need to work with values of 100,000 billions dollars to maybe have a screw up of 1 dollar with `double` – Franck Sep 30 '20 at 15:58
  • 2
    _"For money, **always** decimal. It's why it was created."_ - https://stackoverflow.com/a/1165788/43846 – stuartd Sep 30 '20 at 16:02
  • @Franck write a console app, declare a _double d = 9.99;_ then increment this variable by 0.01 with _d += 0.01;_ for 6 times, finally add a check for _if (d < 10.05) Console.WriteLine("What? Why d value is less than " + d);_ – Steve Sep 30 '20 at 16:21

2 Answers2

2

You are are learning C# might as well jump right in and start developing classes that handle the logic required.

The trick is to start from the highest denomination note and count how many of them fit in the amount. For example

amount = 379
count_100 = amount/100 = 3 // integer division
amount = amount - count_100*100 // remainder 79

The move to the next largest note

count_50 = amount/50 = 1 
amount = amount - count_50*50 // remainder 29

and proceed down to 20,10,5, and 1 notes.

The remainder is the change given out.

For example an BankNotes class that splits up an amount to an array of note count for each denomination.

public struct BankNotes
{
    public readonly static Decimal[] Notes = { 1m, 5m, 10m, 20m, 50m, 100m };
    public static implicit operator BankNotes(decimal value) => new BankNotes(value);
    public static implicit operator decimal(BankNotes amount) => amount.Value;
    public BankNotes(decimal value)
    {
        // Initilize note counts to 0
        this.NoteCount = new int[Notes.Length];
        // Go from lagest note down to smallest
        for (int i = NoteCount.Length - 1; i >= 0; i--)
        {
            // calc count for each note
            NoteCount[i] = (int)(value / Notes[i]);
            // adjust balance based on notes counted
            value -= NoteCount[i] * Notes[i];
        }
        // set the remaining moneys
        Remainder = value;
    }
    public decimal Remainder { get; }
    // Array of count for each note.
    public int[] NoteCount { get; }
    // Total value of notes.
    public decimal NotesValue 
        => Notes.Zip(NoteCount, (note, count) => count * note).Sum();
    // Tota value including remainder (for checK)
    public decimal Value
        => NotesValue + Remainder;
}

And then to be used in a console application by handling the math for the user inputs

class Program
{
    static void Main(string[] args)
    {
        bool done = false;
        const decimal rate = 1.123m;
        do
        {
            Console.WriteLine("Enter Amount in GBP");
            string input = Console.ReadLine();
            if (decimal.TryParse(input, out decimal amount))
            {
                amount = Math.Round(amount * rate, 2); // convert to EUR and round
                Console.WriteLine($"Amount in EUR is {amount}");

                BankNotes bank = new BankNotes(amount);
                for (int i = 0; i < BankNotes.Notes.Length; i++)
                {
                    if (bank.NoteCount[i] > 0)
                    {
                        Console.WriteLine($"  {bank.NoteCount[i]} notes of {BankNotes.Notes[i]} EUR");
                    }
                }
                Console.WriteLine($"  Sum   : {bank.NotesValue} EUR");
                Console.WriteLine($"  Change: {bank.Remainder} EUR");
                Console.WriteLine($"  Error : {bank.Value - amount} EUR");
            }
            else
            {
                done = true;
            }
        } while (!done);
    }
}

Here is a sample output, formatted a but differently though:

scr

JAlex
  • 1,486
  • 8
  • 19
0

You'll need to use remainder division to accomplish this.

The general formula ((value / higher bucket)remainder / current bucket)

Logic sample

Value = 1234.

num of 100s = (1234 / 100) = 12

num of 50s = ((1234 % 100)/50) or (34/50) = 0

num of 20s = ((1234 % 50)/20) or (34/20) = 1

num of 5s = ((1234 % 20)/5) or (14/5) = 2

num of 1s = ((1234 % 5)/1) or (4/1) = 4

twelve 100s, zero 50, one 20s, two 5s and four 1s.

Wes H
  • 4,186
  • 2
  • 13
  • 24