Sunday, March 6, 2011

C# Math Problem

I have been working on this for the greater part of the day and I cant seem to make this part of my code work. The intent of the code is to allow the user to input a set of values in order to calculate the missing value. As an additional feature I placed a CheckBox on the form to allow the user to do further calculation. That is where my problem lies. I know the code works because if I change the formula the value that appears in tb3_aic.Text changes per the formula. However, when I use the below the answer does not change like it should. Please reference the attached code. If a jpg image is needed of the formula I can e-mail it.

 void Calc3Click(object sender, EventArgs e)

 {
       if (String.IsNullOrEmpty(tb3_skv.Text) | String.IsNullOrEmpty(tb3_kva.Text) | String.IsNullOrEmpty(tb3_z.Text))
 {
     MessageBox.Show("Enter all required values", "Missing Data", MessageBoxButtons.OK);
 } //If user does not enter all the values required for the calculation show error message box
 else

 {
  if (!String.IsNullOrEmpty(tb3_skv.Text) & !String.IsNullOrEmpty(tb3_kva.Text) & !String.IsNullOrEmpty(tb3_z.Text))

  { //If motor load check box is not checked and required values are entered calculate AIC based on formula.
   int y; 
   decimal x, z, a;
   x = decimal.Parse(tb3_skv.Text);      
   y = int.Parse(tb3_kva.Text);
   a = decimal.Parse(tb3_z.Text);
   z = (y * 1000) / (x * 1.732050808m) / (a / 100); //the m at the end of the decimal allows for the multiplication of decimals
   tb3_aic.Text = z.ToString();
   tb3_aic.Text = Math.Round(z,0).ToString();
  }


  if (cb3_ml.Checked==true) 
  {//If Motor Load CB is checked calculate the following
   int y, b;
   decimal x, z, a;
   x = decimal.Parse(tb3_skv.Text);
   y = int.Parse(tb3_kva.Text);
   a = decimal.Parse(tb3_z.Text);
   b = int.Parse(tb3_ml.Text);
   z = ((y * 1000) / (x * 1.732050808m) / (a / 100))+((b / 100)*(6*y)/(x*1.732050808m)*1000);
   tb3_aic.Text = z.ToString();
   tb3_aic.Text = Math.Round(z,5).ToString();
  }

  }

I am grateful for any help that can be provided.

Thank you, Greg Rutledge

From stackoverflow
  • Change this:

    int y, b;
    

    To this:

    int y;
    decimal b;
    

    and it works, according to this test:

        public void Test2()
        {
            int y;
            decimal b;
            decimal x, z, a;
            decimal z1, z2;
            x = 480m;
            y = 2500;
            a = 5.75m;
            b = 10;
            z1 = ((y * 1000) / (x * 1.732050808m) / (a / 100));
            z2 = ((b / 100) * (6 * y) / (x * 1.732050808m) * 1000);
            z = z1 + z2;
            Console.WriteLine("{0}, {1}", z1, z2);
            Console.WriteLine(Math.Round(z, 0).ToString());
        }
    

    The reason is that integer 10 divided by integer 100 is integer 0, which zero's the whole z2.

    tejas_grande : I changed all of the variables to decimal. is there any reason to leave y an int???
    David B : No reason at all.
  • I don't know if this is huge but you are setting the text of the tb3_aic textbox twice when maybe you are trying to concatenate?

    tb3_aic.Text = z.ToString();
    tb3_aic.Text = Math.Round(z,0).ToString();
    

    You seem to be doing this in both methods.

    The more that I look at it, this could be an issue since you are setting it in the first if then the second If will overwrite that if the checkbox is checked.

    tejas_grande : If the second formula overwrites the output of the first it is ok since the second formula will produce a different answer. How could I consolidate?
    tejas_grande : Never mind, I see. I am deleting the first text set.
  • Without really knowing what the problem is, a few things look a bit odd:

    • Also, mixing decimal and int in a calculation can lead to unexpected results unless you really know what you are doing. I suggest using only decimals (or doubles, which are way faster and usually have enough precision for engineering computations).
    • You also set tb3_aic.Text twice, I assume you decided on rounding later and forgot to remove the first one.

    Edit: This is apparently wrong in C#:

    • You use bit-wise AND (&) in the if-clause where you probably mean logical AND (&&).

    The only difference between them when used with boolean operands are that && short circuits (doesn't evaluate the right operand if the left is false). I learned something, thank you people commenting. :)

    Gavin Miller : +1 for mixing decimal and int calculations - that's where I'd look first.
    Will Dean : The first point is wrong. They're logical operators not bitwise in this context.
    tejas_grande : Mixing decimal and int was the problem. I changed it and the formula calculated correctly. Thank you very much for that!
    Simucal : I would remove the incorrect statement about the bitwise entirely
  • Sample Inputs, first formula x = 480 y = 2500 a = 5.75

    For the first formula the output should be 52296

    Sample Inputs, second formula x = 480 y = 2500 a = 5.75 b = 10

    For the first formula the output should be 54100.42

    Hope this helps

  • this line isn't needed, although its not a bug, it just always evaluates to true

    if (!String.IsNullOrEmpty(tb3_skv.Text) & !String.IsNullOrEmpty(tb3_kva.Text) & !String.IsNullOrEmpty(tb3_z.Text)) {
    

0 comments:

Post a Comment