0

My assignment was to create a tax calculator in whatever way possible initially with paying tax excluding tax brackets. How would I adjust this code to use Loops instead or how could I make it more efficient?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    double earnings;    //user income
    double tax;         //sum of total tax

    printf("=====================<><>TAX CALCULATOR (INC TAX BRACKETS)<><>=====================\n How much have you earned: \n");
    scanf("%lf", &earnings);
    double tax1 = earnings -12000;      //seperating each tax bracket
    double tax2 = earnings - 20000;
    double tax3 = earnings - 40000;
    double tax4;
    double tax5;
    if (earnings >= 12000 && earnings <=19999){
        tax = (tax1*0.1);
        printf("\nYou've made: %0.2f", earnings - tax);
        printf("\nPaying: %0.2f in tax", tax);
    }
    else if(earnings >= 20000 && earnings <=39999){
        //printf("\n============tax2: %0.2f============\n",tax2);
        //printf("\n============Tax2: %0.2f============\n",tax2*0.15);
        tax = (tax1*0.1 + tax2*0.15);
        printf("\nYou've made: %0.2f", earnings - tax);
        printf("\nPaying: %0.2f in tax", tax);
    }
    else if(earnings >= 40000){
        tax = (tax1*0.1 + tax2*0.15 + tax3*0.2);
        //printf("\n============tax3: %0.2f============\n",tax3);
        //printf("\n============Tax3: %0.2f============\n",tax3*0.2);
        printf("\nYou've made: %0.2f", earnings - tax);
        printf("\nPaying: %0.2f in tax", tax);
    }
    else{
            tax = 0;
            printf("You made %0.2f", earnings);
            printf("Paying: %0.2f", tax);
    }

    return 0;
}
NeonRyse
  • 15
  • 3

2 Answers2

2

You can simplify your conditions, like:

    if (earnings < 12000) {
    } else if (earnings < 20000) {
    } else if (earnings < 40000) {
    } else { // earnings >= 40000 
    }

You can also reduce the "sometimes not needed" pre-calculations, merge consecutive calls to printf and avoid duplicating them everywhere, and replace run-time calculations with compile-time calculations, like:

    const double constTax1 = (20000 - 12000) * 0.1;
    const double constTax2 = (40000 - 20000) * 0.25 + constTax1;
    double tax = 0.0;

    if (earnings < 12000) {
        // Do nothing!
    } else if (earnings < 20000) {
        tax = (earnings - 12000) * 0.1;
    } else if (earnings < 40000) {
        tax = (earnings - 20000) * 0.25 + constTax1;
    } else { // earnings >= 40000 
        tax = (earnings - 20000) * 0.45 + constTax2;
    }
    printf("\nYou've made: %0.2f\nPaying: %0.2f in tax", earnings - tax, tax);

Fortunately, it's likely that the compiler would've done most of these optimizations itself. The biggest performance gain would be from merging the calls to printf() (to reduce/avoid function call overhead).

Note that the compiler is typically prevented from optimizing calls to printf() properly because it's in a different compilation unit (even if you use link-time optimisation it's likely that printf() is in a dynamically linked library).

Brendan
  • 35,656
  • 2
  • 39
  • 66
  • Although this does handle tax brackets the way I would expect, it is not equivalent to the OP. The OP double-taxes income greater than 20000 and triple-taxes income greater than 40000. – EdmCoff Nov 09 '21 at 00:07
  • @EdmCoff: Where does OP double/triple tax? – Brendan Nov 09 '21 at 13:16
  • In the lines `tax = (tax1*0.1 + tax2*0.15)` and `tax = (tax1*0.1 + tax2*0.15 + tax3*0.2)`, tax1 is equal to `earnings-12000` and tax2 is equal to `earnings-20000` (not 20000-12000 and 40000-20000 like one would assume). So, for example, your code taxes income of 100000 as `(20000-12000)*0.1+(40000-20000)*0.15+(100000-40000)*0.2`, but OP does `(100000-12000)*0.1+(100000-20000)*0.15+(100000-40000)*0.2` – EdmCoff Nov 09 '21 at 15:43
  • @EdmCoff: Ah - I see what you're saying. I need to fix my tax multipliers (0.1, 0.15, 0.2 -> 0.1 0.25, 0.45) to match the behavior of OPs code. Thanks :-) – Brendan Nov 09 '21 at 23:33
  • Actually, EdmCoff is correct, I'm new to programming and my intention of the program was to perform as expected and I made an error there having it tax the total at each step rather than the cutoff as expected – NeonRyse Nov 10 '21 at 21:09
0

You could do something like the following to avoid writing the same numbers multiple times and to make it easier to add additional tax brackets. (This almost certainly won't make it any faster, but I do think it could potentially be more maintainable.)

const int nb = 3;
const double taxrate[nb] = {0.1, 0.15, 0.2};
const double taxcutoff[nb] = {12000, 20000, 40000};
double tax = 0;

for (int i = 0; i < nb && earnings > taxcutoff[i]; i++) {
 tax += (earnings - taxcutoff[i]) * taxrate[i];
}
printf("\nYou've made: %0.2f", earnings - tax);
printf("\nPaying: %0.2f in tax", tax);

I believe the above is equivalent to your original code, but this is not how real tax brackets work. It is more likely you want something like:

const int nb = 3;
const double taxrate[nb] = {0.1, 0.15, 0.2};
const double taxcutoff[nb] = {12000, 20000, 40000};
double bracketearnings;
double tax = 0;

for (int i = 0; i < nb && earnings > taxcutoff[i]; i++) {
 if (i == nb-1 || earnings < taxcutoff[i+1]) {
    bracketearnings = earnings - taxcutoff[i];
 }
 else {
    bracketearnings = taxcutoff[i+1] - taxcutoff[i];
 }
 tax += bracketearnings * taxrate[i];
}
printf("\nYou've made: %0.2f", earnings - tax);
printf("\nPaying: %0.2f in tax", tax);

Edited to explain the loop as requested: In both cases, I am using nb=3 to keep track of how many tax brackets there are. The loop will go through each item of the array (or until 'earnings > taxcutoff[I]` is not true).

In the second example, it checks whether the next bracket doesn't exist (i == nb-1) or if the earnings "end" in this tax bracket (earnings < taxcutoff[i+1]). If so, it uses earnings minus the current taxcutoff as the bracketearnings, otherwise it uses the next bracket cutoff minus the current cutoff as the bracketearnings. In either case, it multiplies the bracketearnings by the current taxrate and adds it to tax. Tax is a running total that gets added to on each iteration of the loop.

The advantage compared to your original idea is if you wanted to add another tax bracket (or 100 more), you only need to change the first 3 lines, since the logic is the same for each of them.

EdmCoff
  • 3,506
  • 1
  • 9
  • 9
  • Thank you, You are correct in stating the difference between what I programmed and how it actually functions and I made the mistake myself. Could you elaborate on how that for loop functions for me a bit, I'm new to programming and trying to understand how things function and why they are used. – NeonRyse Nov 10 '21 at 21:14
  • I've added some additional information about how the loops work to my answer. I hope that helps. – EdmCoff Nov 10 '21 at 21:33