locked
"Arithmetic operation resulted in an overflow." error in VB code but not in C# code RRS feed

  • Question

  • Hi,

    I have an application in which I am communicating with a 2d profiler (generates a data array from a 2d CMOS sensor, like a camera, except that is uses triangulation with a laser line to detect height variances due to the location of the reflected light which changes along one direction (columns) of the sensor based on the distance from the object at the point of reflection to the face of the laser/sensor pair).  The methodology is that the sensor rows represent points along the length of the laser stripe, while the columns return the corresponding position of the reflected light (analogous to the object to sensor distance), hence, a 2d scan.

    The data are returned to an array and processed for drawing into a picture box, representing this 2d profile.

    My issue is this.  I have C# code which works fine, and a converted equivalent in VB which gives the exception "Arithmetic operation resulted in an overflow."

    The problem seems to be with the array ==> mem_read_commnad.  I have determined this by commenting out the statements where these are set, one by one.  

    Elements mem_read_commnad[6] and mem_read_commnad[7] seem to be the culprits, however, I would think that the array itself is generating the wrong values, which are precipitating the erroneous values.

    A copy of the source code and pertinent values obtained for each version follows:

    C# Version

    VALUES OBTAINED:

         mem_read_commnad ==> {2, 3, 0, 2, 0, 0, 0, 0, 0, 17, 3, 0}

         recv_data ==> {2, 2, 64, 11, 0, 122, 208, 0, 3, 227, 0, 0, 0, 0, 0}

         a = address = 8048640 (first time through loop)

    CODE:

    private void getProfileButton_Click(object sender, EventArgs e)
            {
                try
                {
                    int tc = Environment.TickCount;
                    var recv_data = new byte[255 * 2 + 6];

                    //Getting latest profile address
                    var get_naddr_command = new byte[] { STX, 0, 0x40, 0x0B, ETX, 0 };
                    get_naddr_command[5] = calc_bcc(get_naddr_command);
                    serialPort1.Write(get_naddr_command, 0, 6);
                    WaitReply(recv_data, 10);
                    int address = (recv_data[4] << 24) + (recv_data[5] << 16) + (recv_data[6] << 8) + recv_data[7];

                    int nwords = 10000;
                    int a = address;
                    int j = 0;
                    for (; nwords > 0; )
                    {
                        int n;
                        if (nwords <= 253)
                            n = nwords;
                        else
                            n = 253;
                        var mem_read_commnad = new byte[12] { STX, 3, 0x00, 0x02, 0, 0, 0, 0, 0, 0x11, ETX, 0 };
                        mem_read_commnad[4] = (byte)(a >> 24);
                        mem_read_commnad[5] = (byte)(a >> 16);
                        mem_read_commnad[6] = (byte)(a >> 8);
                        mem_read_commnad[7] = (byte)(a);
                        mem_read_commnad[8] = (byte)n;
                        mem_read_commnad[11] = calc_bcc(mem_read_commnad);
                        serialPort1.Write(mem_read_commnad, 0, 12);
                        int ret = WaitReply(recv_data, 255 * 2 + 6);
                        if (nwords > 9999)
                        {
                            ushort w0 = (ushort)((recv_data[8] << 8) | recv_data[9]);
                            profile_size = (w0 >> 5);
                            nwords = profile_size * 2 + 2;
                        }
                        for (int i = 0; i < n; i++)
                        {
                            profile[j++] = (short)((recv_data[8 + 2 * i] << 8) + recv_data[9 + 2 * i]);
                            //profile[j++] = (short)((recv_data[10+4*i]<<8) + recv_data[11+4*i]);
                        }
                        nwords -= n;
                        a += n;
                    }
                    profileImage.Refresh();
                }
                catch (Exception ex)
                {
                    intervalProfile.Checked = false;
                    MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }

    VB Version

    VALUES OBTAINED:

         mem_read_commnad ==> {2, 3, 0, 2, 0, 0, 0, 0, 0, 17, 3, 0}

         recv_data ==> {2, 2, 64, 11, 0, 142, 64, 0, 3, 135, 0, 0, 0, 0, 0}

         a = address = 9322496 (first time through loop)

    CODE:

    Private Sub getProfileButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles getProfileButton.Click
    Try
    Dim tc As Integer = Environment.TickCount
    Dim recv_data = New Byte((255 * 2 + 6) - 1){}

    'Getting latest profile address
    Dim get_naddr_command = New Byte() { STX, 0, &H40, &HB, ETX, 0 }
    get_naddr_command(5) = calc_bcc(get_naddr_command)
    serialPort1.Write(get_naddr_command, 0, 6)
    WaitReply(recv_data, 10)
    Dim address As Integer = (CInt(recv_data(4)) << 24) + (CInt(recv_data(5)) << 16) + (CInt(recv_data(6)) << 8) + recv_data(7)

    Dim nwords As Integer = 10000
    Dim a As Integer = address
    Dim j As Integer = 0
    Do While nwords > 0
    Dim n As Integer
    If nwords <= 253 Then
    n = nwords
    Else
    n = 253
    End If
    Dim mem_read_commnad = New Byte(11) { STX, 3, &H0, &H2, 0, 0, 0, 0, 0, &H11, ETX, 0 }
    mem_read_commnad(4) = CByte(a >> 24)
    mem_read_commnad(5) = CByte(a >> 16)
    mem_read_commnad(6) = CByte(a >> 8)
    mem_read_commnad(7) = CByte(a)
    mem_read_commnad(8) = CByte(n)
    mem_read_commnad(11) = calc_bcc(mem_read_commnad)
    serialPort1.Write(mem_read_commnad, 0, 12)
    Dim ret As Integer = WaitReply(recv_data, 255 * 2 + 6)
    If nwords > 9999 Then
    Dim w0 As UShort = CUShort((CInt(recv_data(8)) << 8) Or recv_data(9))
    profile_size = (CInt(w0) >> 5)
    nwords = profile_size * 2 + 2
    End If
    For i As Integer = 0 To n - 1
    profile(j) = CShort((CInt(recv_data(8 + 2 * i)) << 8) + recv_data(9 + 2 * i))
    j += 1
    'profile[j++] = (short)((recv_data[10+4*i]<<8) + recv_data[11+4*i]);
    Next i
    nwords -= n
    a += n
    Loop
    profileImage.Refresh()
    Catch ex As Exception
    intervalProfile.Checked = False
    MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Try
    End Sub


    Any ideas would be greatly appreciated!!!

    Thanks!

    Wednesday, August 13, 2014 8:34 PM

Answers

  • Hello,

    In C# Checked and Unchecked is used.

    string Test = "2147483647";
    int Value = Convert.ToInt32(Test);
    int Result = unchecked(Value + 2);
    if (Result >0)
    {
        Console.WriteLine("Positive");
    }
    else
    {
        Console.WriteLine("Negative");
    }
    
    


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.

    Wednesday, August 13, 2014 9:17 PM
  • By default, C# does not check for integer overflow while VB does.

    You can change this in the projects settings for your VB project.  On the Compile Tab, click the "Advanced Compile Options" button.  On that dialog, check the box called "Remove integer overflow checks"

    By the way, the array recv_data seems to have different values in the VB version when compared to the C# version.  Is that intentional?

    Wednesday, August 13, 2014 8:40 PM

All replies

  • By default, C# does not check for integer overflow while VB does.

    You can change this in the projects settings for your VB project.  On the Compile Tab, click the "Advanced Compile Options" button.  On that dialog, check the box called "Remove integer overflow checks"

    By the way, the array recv_data seems to have different values in the VB version when compared to the C# version.  Is that intentional?

    Wednesday, August 13, 2014 8:40 PM
  • Chris,

    Thank you!!!  This did it.

    BTW, the values recv_data value contains the sensor result data, which changes a bit from scan to scan, depending on the lighting and movement of the setup.  The unit is not very well secured on the bench, but will be in the system.

    Do you know why "remove integer overflow checks" is required in VB but not C#?  I know the these differ a bit in how data types are handled/processed, but not sure about this issue.  Also, is there any penalty with removing the checks?

    Thanks, again!

    Wednesday, August 13, 2014 9:08 PM
  • Hello,

    In C# Checked and Unchecked is used.

    string Test = "2147483647";
    int Value = Convert.ToInt32(Test);
    int Result = unchecked(Value + 2);
    if (Result >0)
    {
        Console.WriteLine("Positive");
    }
    else
    {
        Console.WriteLine("Negative");
    }
    
    


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.

    Wednesday, August 13, 2014 9:17 PM
  • Do you know why "remove integer overflow checks" is required in VB but not C#?  I know the these differ a bit in how data types are handled/processed, but not sure about this issue.  Also, is there any penalty with removing the checks?

    I don't know why that option is checked by default in VB.   Perhaps Microsoft chose that as the default because it's the safest option when converting older VB6 code.

    Friday, August 15, 2014 8:42 PM