-2

Code:

#include <stdio.h>
    int main(void)
    {
        int coins = 0;
        float cash_owed = 0;
        printf("Cash owed: ");
        scanf("%f" , &cash_owed);
        while(cash_owed > 0)
        {
            if(cash_owed >= 0.25)
            {
                cash_owed -= 0.25;
                coins++;
            }
            else if(cash_owed >= 0.10)
            {
                cash_owed -= 0.10;
                coins++;
            }
            else if(cash_owed >= 0.05)
            {
                cash_owed -= 0.05;
                coins++;
            }
            else if(cash_owed >= 0.01) 
            {
                cash_owed -= 0.01;
                coins++;
            }
        }
        printf("%i\n", coins);
        return 0;
    }

So basically this is a greedy algorithm. It takes cash owed as inputs, Evaluates the minimum no. of coins to give. (US Currency). I think there is so much repeatation in my code. It's not optimized. Can someone help me out here?

lookabove
  • 19
  • 1
  • 1
    What kind of optimization are you looking for? Runtime? Codesize? Executable size? Program image size? If it's codesize, you can reduce it by deleting the indentation. – EOF Sep 26 '20 at 17:39
  • 1
    If you don't specify what you're optimizing for, usually "speed" is assumed and "not optimized" means "doesn't work fast enough", which is unrelated to code repetition. Are you only looking to remove repetition, or also to make it faster? – HolyBlackCat Sep 26 '20 at 17:39
  • 1
    There is an analytical solution to your problem using modulo. No need for the while loop. You could store the coin values in an array and go from the largest to smallest coins. – Quimby Sep 26 '20 at 17:40
  • 4
    Storing money amount in a floating-point variable is dangerous. You're risking ending up with `$ 0.2999994` (or whatever) due to precision problems. Store the number in an `int`, measured in cents. – HolyBlackCat Sep 26 '20 at 17:42
  • @Quimby Can you please elaborate? I'm looking for exactlty that method – lookabove Sep 26 '20 at 17:48
  • @HolyBlackCat Can't I just round it upto 2 decimal places? – lookabove Sep 26 '20 at 17:50
  • @EOF I want to just reduce repetition – lookabove Sep 26 '20 at 17:51
  • @lookabove Its the same as converting seconds to hours,minutes, and seconds. You just go from the largest coin, compute div + remainder and continue with remainder and smaller coins. – Quimby Sep 26 '20 at 17:52
  • *"Can't I just round it upto 2 decimal places?"* It's not that easy. Some numbers (e.g. even `0.1`) can't be represented exactly in binary. They have an infinite amount of binary digits after the `.`, and since a `float` can only store a finite amount of binary digits, so you won't be able to store `0.1` exactly (try running `std::cout << std::setprecision(1000) << 0.1f << '\n';`). – HolyBlackCat Sep 26 '20 at 18:47

2 Answers2

3

Firstly, you should never (unless you come of with a good reason, and "there are 100 cents in one dollar" is not a good reason) use floating point numbers for currency. They can generate rounding error bugs. Use integers instead, and format output later.

And using that, I would do something like this:

int coins = 0;
int cash_owed = 0;
printf("Cash owed (in cents): ");
scanf("%d" , &cash_owed);

int coin_type[] = {25, 10, 5, 1};

for(int i=0; i<sizeof(coin_type)/sizeof(coin_type[0]); i++) {
    while(cash_owed >= coin_type[i]) {
        cash_owed -= coin_type[i];
        coins++;
    }
}

Here is an example of how to print currency:

int cents = 7334;
printf("$%d.%d", cents/100, cents%100);
klutt
  • 30,332
  • 17
  • 55
  • 95
0

There is no need to increment the coins one by one. As comments suggested, use integers, not floats for currency.

#include <stdio.h>
int main(void)
{
    int total_coins = 0;
    int cash_owed = 0;
    printf("Cash owed in cents: ");
    scanf("%d" , &cash_owed);

    // Coins from largest to smallest.
    int coins[4]={25,10,5,1};

    for(int i=0;i<4;++i){
        total_coins+= cash_owed/coins[i];
        cash_owed%=coins[i];
    }
    // cash_owed contains remainder that cannot be paid with the coins.

    printf("%d\n", total_coins);
    return 0;
}
Quimby
  • 17,735
  • 4
  • 35
  • 55
  • But what if user enters 0.41, We have to check the values for 0.41, 0.01 ,0.15,1.6, 23, 4.2, "", foo – lookabove Sep 26 '20 at 18:06
  • @lookabove Afraid, I do not understand the *1.6, 23, 4.2, "", foo* part. The user should enter the value in cents. If you insists on floats, only use them for input and convert to integers early. Repeated arithmetic on floats can be lossy. – Quimby Sep 26 '20 at 18:08
  • Ok, So we have a test. We have to create a program which takes a decimal input of change owed. This should not take negetive numbers, no charaters and no other data type. Sorry I'm kinda new to programming so I might have been unclear at first – lookabove Sep 26 '20 at 18:11
  • @lookabove In that case you can take advice from klutt 's comment under his answer - input is float but convert it to cents immediately. – Quimby Sep 26 '20 at 18:15