Search code examples
vb.netrounding-error

VB.NET doesn't round numbers correctly?


I'm testing the speed of some functions so I made a test to run the functions over and over again and I stored the results in an array. I needed them to be sorted by the size of the array I randomly generated. I generate 100 elements. Merge sort to the rescue! I used this link to get me started.

The section of code I'm focusing on:

private void mergesort(int low, int high) {
// check if low is smaller then high, if not then the array is sorted
    if (low < high) {
      // Get the index of the element which is in the middle
      int middle = low + (high - low) / 2;
      // Sort the left side of the array
      mergesort(low, middle);
     // Sort the right side of the array
      mergesort(middle + 1, high);
     // Combine them both
      merge(low, middle, high);
   }
}

which translated to VB.NET is

    private sub mergesort(low as integer, high as integer)
    ' check if low is smaller then high, if not then the array is sorted
        if (low < high)
      ' Get the index of the element which is in the middle
          dim middle as integer = low + (high - low) / 2
      ' Sort the left side of the array
          mergesort(low, middle)
      ' Sort the right side of the array
          mergesort(middle + 1, high)
      ' Combine them both
          merge(low, middle, high)
    end if
end sub

Of more importance the LOC that only matters to this question is

dim middle as integer = low + (high - low) / 2

In case you wanna see how merge sort is gonna run this baby

high   low                     high   low
100     0                      10      0
50      0                       6      4
25      0                       5      4
12      0                      12      7
6       0                      10      7
3       0                       8      7
2       0                  :stackoverflow error:

The error comes from the fact 7 + (8 - 7) / 2 = 8. You'll see 7 and 8 get passed in to mergesort(low, middle) and then we infinite loop. Now earlier in the sort you see a comparison like this again. At 5 and 4. 4 + (5 - 4) / 2 = 4. So essentially for 5 and 4 it becomes 4 + (1) / 2 = 4.5 = 4. For 8 and 7 though it's 7 + (1) / 2 = 7.5 = 8. Remember the numbers are typecasted to an int.

Maybe I'm just using a bad implementation of it or my typecasting is wrong, but my question is: Shouldn't this be a red flag signaling something isn't right with the rounding that's occuring?


Solution

  • Without understanding the whole algorithm, note that VB.NET / is different than C# /. The latter has integer division by default, if you want to truncate decimal places also in VB.NET you have to use \.

    Read: \ Operator

    So i think that this is what you want:

    Dim middle as Int32 = low + (high - low) \ 2