Reputation: 23
I've looked up examples of doing this but when I try to format the code like it, it doesn't work. Here is the program I want to convert.
#include <stdio.h>
double comp_tax(double salary);
int
main(void)
{
double salary, tax;
printf("Input your annual salary >$ ");
scanf_s("%lf", &salary);
tax = comp_tax(salary);
if (tax != -1.0)
printf("your tax is $%.2f", tax);
else
printf("your salary is outside the table ranged");
return 0;
}
double
comp_tax(double salary)
{
double tax;
if (salary < 0.0)
tax = -1.0;
else if (salary < 15000.00)
tax = 0.15 * salary;
else if (salary < 30000.00)
tax = (salary - 15000.00) * 0.18 + 2250.00;
else if (salary < 50000.00)
tax = (salary - 30000.00) * 0.22 + 5400.00;
else if (salary < 80000.00)
tax = (salary - 50000.00) * 0.27 + 11000.00;
else if (salary <= 150000.00)
tax = (salary - 80000.00) * 0.33 + 21600.00;
else
tax = -1.0;
return (tax);
}
Upvotes: 1
Views: 184
Reputation: 117642
switch
can only be used to compare integers for equality with the constexpr
integers in the case
s.
I suggest creating a std::map
with the threshold values as Keys mapped to functions to make the lookup fast and easy. I also suggest not writing the program with hardcoded formulas since you'll have to recalculate those formulas every time a threshold value or percentage changes. Instead, you could add a function that creates this map
the first time the comp_tax()
function is called and keeps it for the rest of the programs execution.
Example:
#include <cmath>
#include <functional>
#include <initializer_list>
#include <limits>
#include <map>
#include <utility>
auto make_salary_tax_map() {
std::map<double, std::function<double(double)>> retval;
// the thresholds and the percentages - simple to maintain
static const std::initializer_list<std::pair<double, double>> salary_tax = {
{ 0., .00},
{ 15000., .15},
{ 30000., .18},
{ 50000., .22},
{ 80000., .27},
{std::nextafter(150000, 300000.), .33}, // to match the <= in your comp_tax()
{std::numeric_limits<double>::max(), .33}, // salary > 150000, percentage?
};
double prev_threshold = 0.;
double add = 0.;
double threshold;
double percent;
for(auto& st : salary_tax) {
std::tie(threshold, percent) = st;
// decrease the threshold a little to be able to use lower_bound,
// except for the max value for a double.
double th = threshold == std::numeric_limits<double>::max()
? threshold
: std::nextafter(threshold, 0.);
// store the function for this threshold:
retval[th] = [=](double s) { return (s - prev_threshold) * percent + add; };
prev_threshold = threshold;
add = threshold * percent;
}
return retval;
}
With that in place your comp_tax()
function simply becomes:
double comp_tax(double salary) {
// static, so it's only initialized once:
static const auto salary_tax = make_salary_tax_map();
// efficiently find the function for this salary and call it
return salary_tax.lower_bound(salary)->second(salary);
}
Upvotes: 0
Reputation: 17668
The sequence of if/else
cases is the more natural representation.
If the code must be coerced into a switch
statement for whatever reason, the following could be one such possible obfuscation.
double comp_tax(double salary)
{
double tax = 0;
double ks = salary / 1000;
switch((ks > 0) * ((ks < 15) + (ks < 30) + (ks < 50) + (ks < 80) + (ks <= 150)))
{
case 1: tax += (ks - 80) * 0.33; ks = 80;
case 2: tax += (ks - 50) * 0.27; ks = 50;
case 3: tax += (ks - 30) * 0.22; ks = 30;
case 4: tax += (ks - 15) * 0.18; ks = 15;
case 5: tax += ks * 0.15; return tax * 1000;
}
return -1;
}
Note: the above calculates the progressive tax for salaries up to 150K using the given brackets and rates. It will not match OP's numbers above 30K, because the original code has dubious "jumps", for example comp_tax(29999.99) == 4950
but comp_tax(30000.00) == 5400
.
Upvotes: 0
Reputation: 6657
switch
statement can only be used if the condition can equal to an integer case. For instance:
int n;
std::cin >> n;
switch(n)
{
case 0:
// do something if n == 0
break;
case 1:
// do something if n == 1
break;
default:
// otherwise, do this
}
In your case, you are not switching based on logics like salary == n
, so you cannot use a switch
statement.
Technically you can:
switch(static_cast<int>(salary) / 5000):
{
case 3:
case 4:
case 5:
tax = 0.15 * salary;
break;
case 6:
case 7:
case 8:
case 9:
tax = (salary - 15000.00) * 0.18 + 2250.00;
break;
.
.
.
default:
tax = -1;
}
But that's probably not what you wanted to do with switch
.
Upvotes: 1