Convert decimal to currency and back - c#

It's a little more complicated than that, but this is my code:
private void button1_Click(object sender, EventArgs e)
{
Decimal num1 = Convert.ToDecimal(textBox1.Text);
Decimal num2 = Convert.ToDecimal(textBox2.Text);
Decimal total = num1 + num2;
textBox3.Text = total.ToString("C");
Decimal total2 = Convert.ToDecimal(total);
total2 = total * 4.2;
textBox4.Text = Convert.ToString(total2);
Basically it's this: I have 4 text boxes, and I want to be able to put in a number in box1 and box2. Box three will multiply box 1 & 2 and convert it to currency. Box four will take Box 3s value and change it back to decimal and multiply a number. I can get it to work as long as total2 does not have a decimal. When it has one it will fail.
The program is basically a cash register program that you put in the following:
QTY (box 1)
Amonunt (box 2)
Subtotal (box 3)
Total (box 4)
Any ideas will be helpful.
Thanks,
Caleb

If I understand the problem correctly you perform operations on decimal variables holding currency values. Often it means maintaining a specific resolution (e.g 2 digits after decimal point for cents). Since Decimal is a general purpose type you need to maintain the required resolution programmatically.
example:
static Decimal RoundToCents(Decimal value)
{
return Math.Round(value, 2, MidpointRounding.AwayFromZero);
}
Decimal num1 = RoundToCents(Convert.ToDecimal(textBox1.Text));
Decimal num2 = RoundToCents(Convert.ToDecimal(textBox2.Text));
Decimal total = num1 + num2; // no rounding is needed for additions and subtractions
Decimal total2 = RoundToCents(total * 4.2m);

The fundamental problem is that you are mixing decimal and double in this line:
total2 = total * 4.2;
total is decimal and 4.2 is a double literal. To write a decimal literal use the m suffix.
total2 = total * 4.2m;

Related

Decimals not rounding properly

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();
}
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.
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.

How do i get the total average?

private void txtFinal_Leave_1(object sender, EventArgs e)
{
int prelim;
int midterm;
int final;
decimal average;
string remarks;
prelim = int.Parse(txtPrelim.Text);
midterm = int.Parse(txtMidterm.Text);
final = int.Parse(txtFinal.Text);
average = (prelim + midterm + final) / 3;
txtAverage.Text = average.ToString();
if (average >= 75)
{
remarks = "passed";
}
else
{
remarks = "failed";
}
txtRemarks.Text = remarks;
// this is the output 83 passed
// I want to be like this 83.25 passed
}
average = (prelim + midterm + final) / 3.0m;
This will fix your problem.
Int is an integer type; dividing two ints performs an integer division, i.e. the fractional part is truncated since it can't be stored in the result type (also int!). Decimal, by contrast, has got a fractional part. By invoking Decimal.Divide, your int arguments get implicitly converted to Decimals.
You can enforce non-integer division on int arguments by explicitly casting at least one of the arguments to a floating-point type, e.g.: 3.0m this is casting to decimal !
please upgrade your code as follow:
average = Convert.ToDecimal(prelim + midterm + final) / 3;
txtAverage.Text = string.Format("{0:0.00}", average);

Converting between negative Hexadecimal and negative Decimal gives wrong results

I am attempting to manually convert numbers between decimal and hexadecimal. I have it working for positive numbers and converting a negative decimal to 'negative' hexadecimal but I can't convert it from 'negative' hexadecimal to negative decimal.
Here is the code I am attempting to work with:
private string HexToDecimal(char[] toConvert)
{
if (negativeValue)
{
negativeValue = false;
long var = Convert.ToInt64(HexToDecimal(ResultLabel.Text.ToCharArray()));
long valueToHex = var - (long)Math.Pow(16, 15);
return ResultLabel.Text = valueToHex.ToString();
}
else
{
double total = 0;
//Convert hex to decimal
HexOrDecimalLabel.Text = "Decimal";
//TODO: create int array from indivial int
char[] charArray = toConvert;
long[] numberArray = HexSwitchFunction(charArray);
//TODO: reverse array
Array.Reverse(numberArray);
//loop array, times value by 16^i++, adding to total. This is the method used to convert hex to decimal
double power = 0;
foreach (int i in numberArray)
{
total += (i * (Math.Pow(16, power)));
power++;
}
//set the result label to total
isHex = false;
AllowHexButtons();
return ResultLabel.Text = total.ToString();
}
}
For instance, I can turn - 10 into FFFFFFFFFFFFFFF6, but when i attempt to turn that into decimal, I get 1.15292150460685E+18, which I can't do any equations with.
Does anyone know of a way around this?
This is because double uses a different representation for negative numbers. Changing the type of total and power from double to long will fix the problem.

I am having trouble calling another method

I am not sure if I am doing it right, but I am trying to get the CalculateGrossPay method to run when I click the CalculateBttn_Click button during run time. However, I get random syntax errors that constantly change for whatever reason. I do not change any to make that happen. I am supposed to make a separate method to calculate the gross pay.
private void CalculateBttn_Click(object sender, EventArgs e)
{ CalculateGrossPay(decimal hours, decimal rate);
}
private decimal CalculateGrossPay(decimal hours, decimal rate)
{
decimal result=0.00m;
decimal standardHours= 0.00m;
decimal overtimeHours=0.00m;
if (hours > 40)
{
overtimeHours = (hours - 40) * ( (rate) * 1.5m);
standardHours = 40 * rate;
DisplayOutPut.Text = name+ NameTextBox.Text + "";
DisplayOutPut.Text = "Gross Pay:" + result;
}
else
{
standardHours = hours * rate;
DisplayOutPut.Text = "Hours:" + HoursTextBox.Text;
DisplayOutPut.Text = "Rate:" + RateTextBox.Text;
}
result = standardHours + overtimeHours;
return result;
}
Methods in C# that specify parameters need to be called with Parameters. CalculateGrossPay defines 2 Parameters the hours and the rate as decimal values.
Therefore you need to call CalculateGrossPay with two decimal values as Parameters (see example).
Please visit the following sites for more information:
Methods MSDN
Variables MSDN
Example:
CalculateGrossPay(10.1,0.4);
The error is in the way you are calling the method. You should the call to your method to something like this:
decimal hours = 1;
decimal rate = 5;
CalculateGrossPay(hours, rate);
The values of hours and rate can be hardcoded or you can read them from the user interface.

Convert string to double with 2 digit after decimal separator

All began with these simple lines of code:
string s = "16.9";
double d = Convert.ToDouble(s);
d*=100;
The result should be 1690.0, but it's not. d is equal to 1689.9999999999998.
All I want to do is to round a double to value with 2 digit after decimal separator.
Here is my function.
private double RoundFloat(double Value)
{
float sign = (Value < 0) ? -0.01f : 0.01f;
if (Math.Abs(Value) < 0.00001) Value = 0;
string SVal = Value.ToString();
string DecimalSeparator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator;
int i = SVal.IndexOf(DecimalSeparator);
if (i > 0)
{
int SRnd;
try
{
// вземи втората цифра след десетичния разделител
SRnd = Convert.ToInt32(SVal.Substring(i + 3, 1));
}
catch
{
SRnd = 0;
}
if (SVal.Length > i + 3)
SVal = SVal.Substring(0, i + 3);
//SVal += "00001";
try
{
double result = (SRnd >= 5) ? Convert.ToDouble(SVal) + sign : Convert.ToDouble(SVal);
//result = Math.Round(result, 2);
return result;
}
catch
{
return 0;
}
}
else
{
return Value;
}
But again the same problem, converting from string to double is not working as I want.
A workaround to this problem is to concatenate "00001" to the string and then use the Math.Round function (commented in the example above).
This double value multiplied to 100 (as integer) is send to a device (cash register) and this values must be correct.
I am using VS2005 + .NET CF 2.0
Is there another more "elegant" solution, I am not happy with this one.
Doubles can't exactly represent 16.9. I suggest you convert it to decimal instead:
string s = "16.9";
decimal m = Decimal.Parse(s) * 100;
double d = (double)m;
You might just want to keep using the decimal instead of the double, since you say you'll be using it for monetary purposes. Remember that decimal is intended to exactly represent decimal numbers that fit in its precision, while double will only exactly represent binary numbers that do.
Math.Round(number, 1)
Edit I got the wrong question - the rounding problems are inherent to a floating point type (float, double). You should use decimal for this.
The best solution for not going be crazy is:
string s = "16.9";
For ,/.
double d = Convert.ToDouble(s.Replace(',','.'),System.Globalization.CultureInfo.InvariantCulture);
For rounding:
Convert.ToDouble((d).ToString("F2"));

Categories

Resources