Reputation: 159
I am having an issue with rounding on a c# Payroll program.
I tested it with 15.50 hourly rate x 39.75 hours. This comes to $616.125 gross pay, rounded up to $616.13 gross.
Then I did a fixed Income tax of 25%, which means the final Net Pay of (15.50 x 39.75) x .25 = 462.10
However it keeps displaying a Net Pay of 462.09, so it must not be using the rounded gross pay for the display part. The Gross Pay and Income tax are displaying correctly
Here is all of the code, my guess is that this line needs to be changed among others:
decimal incomeTax = Math.Round(grossPay, 3) * taxRate;
Any ideas what I need to do to get it to round correctly?
decimal hourlyRate = 0;
decimal hoursWorked = 0;
decimal grossPay = 0m;
decimal incomeTax = 0m;
decimal netPay = 0m;
decimal taxRate = .25m;
private void btnCalculate_Click(object sender, EventArgs e)
{
decimal hourlyRate = Convert.ToDecimal(txtHourlyRate.Text);
decimal hoursWorked = Convert.ToDecimal(txtHoursWorked.Text);
decimal grossPay = Math.Round(hourlyRate * hoursWorked, 3);
decimal incomeTax = Math.Round(grossPay, 3) * taxRate;
decimal netPay = grossPay - incomeTax;
txtGrossPay.Text = grossPay.ToString("c");
txtIncomeTax.Text = incomeTax.ToString("c");
txtNetPay.Text = netPay.ToString("c");
}
private void btnClear_Click(object sender, EventArgs e)
{
hourlyRate = 0;
hoursWorked = 0;
grossPay = 0m;
incomeTax = 0m;
netPay = 0m;
txtHourlyRate.Text = "";
txtHoursWorked.Text = "";
txtGrossPay.Text = "";
txtIncomeTax.Text = "";
txtNetPay.Text = "";
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
Upvotes: 1
Views: 229
Reputation: 1785
decimal grossPay = Math.Round(hourlyRate * hoursWorked, 3);
returns 616.125
, for which the rest of the calculations correctly lead to 462.09....
.
It should be
decimal grossPay = Math.Round(hourlyRate * hoursWorked, 2, MidpointRounding.AwayFromZero);
Note the second parameter, the decimal place to round to, is 2 instead of 3, and the MidpointRounding parameter which will round 616.125
to 616.13
and get the result you expect.
Upvotes: 0
Reputation: 63772
616.125
undergoes midpoint rounding. decimal
uses banker's rounding by default. So (and this is something you can check yourself very easily if you just step through your code):
Math.Round(616.125M, 2) // 616.12M
Of course, you're also rounding to three decimal places, so you're actually getting 616.125M
instead of 616.12M
(or 616.13M
) anyway.
You're doing something quite dangerous - you're guessing around tax calculations. Don't do that. Find the applicable tax laws - they will have the exact method used for calculating taxes. Follow those to a T. They specify where and when and how you should round anything. Most likely, all rounding (except for the final price/tax) is supposed to be done to four decimal places, not two, but again, don't guess - read the laws, and make sure you understand them perfectly.
Upvotes: 2