Function drawCurve(ByVal e As Graphics, ByVal coords() As Single) As String
Dim curvePen As New Pen(Color.DarkBlue, 2)
'Create a Point array
Dim curvePoints(coords.Length / 2) As Point ' needed to add -1 here due to weird VB rounding-jmm!
Dim cmsg As String = ""
'Multiply by 10 to increase precision
Dim ctr As Integer = 0
While ctr < coords.Length - 1
cmsg += " (" + coords(ctr).ToString() + "," + coords(ctr).ToString() + ")"
'6.5 becomes 65, for example
coords(ctr) = coords(ctr) * GRID
ctr += 1
End While
'Populate the Point array with coordinate values
ctr = 0
While ctr < coords.Length - 1
'One Point object for each two coordinate values
curvePoints(CInt((ctr / 2))) = New Point(CENTER + CInt(coords(ctr)), CENTER - CInt(coords((ctr + 1))))
'x value
'y value
ctr += 2 'get sets of 2
End While
'Draw curve to the chart
e.DrawCurve(curvePen, curvePoints)
Return cmsg
End Function
[.net] VB.NET rounding issue
Can anyone explain why 26/2 =14 in VB?
At least that's what this piece of code is insisting on under VB2005:
specifically this line:
Dim curvePoints(coords.Length / 2) As Point keeps making my point array 14 instead of 13 as you would think. I also have the same code in C# and under C# it returns 13 as it should.
Are you sure coords length is 26 and not 27? VB does banker's rounding rather than truncation - that means that if the divided number falls on a .5, it gets rounded to the nearest even number, not truncated to the lowest one. If you want truncation, you can use the int() function, that will truncate your division.
(Btw, if the coords array was defined as "new single(26){}", or dim coords(26) as single, that array has 27 elements. VB array initializations takes the upper bound of the array, not the number of elements)
As a curiosity, the idea behind banker's rounding is that rounding errors tend to cancel each other out, instead of tending to accumulate one way or the other.
(Btw, if the coords array was defined as "new single(26){}", or dim coords(26) as single, that array has 27 elements. VB array initializations takes the upper bound of the array, not the number of elements)
As a curiosity, the idea behind banker's rounding is that rounding errors tend to cancel each other out, instead of tending to accumulate one way or the other.
Quote:Original post by alexmoura
Are you sure coords length is 26 and not 27? VB does banker's rounding rather than truncation - that means that if the divided number falls on a .5, it gets rounded to the nearest even number, not truncated to the lowest one. If you want truncation, you can use the int() function, that will truncate your division.
(Btw, if the coords array was defined as "new single(26){}", or dim coords(26) as single, that array has 27 elements. VB array initializations takes the upper bound of the array, not the number of elements)
As a curiosity, the idea behind banker's rounding is that rounding errors tend to cancel each other out, instead of tending to accumulate one way or the other.
Yeah I thought about that too at first but I just ran through the debugger again and it's still showing coords.length as 26 not 27. So how can rounding even apply to 26/2 since there is no fractional part?
The problem isn't rounding, you're effectively doing:
dim curvePoints(13) as Point
In VB, this creates an array with 14 members, numbered from 0 to 13.
dim curvePoints(13) as Point
In VB, this creates an array with 14 members, numbered from 0 to 13.
Doh the array off by 1 error strikes again!
In previous versions of VB the first element started at 1 not 0 so it's a common mistake to make.
Not to mention the syntax is backwards compared to C#.
Looking at the original C# code I was trying to convert it's easy to see now the problem.
The original C# array didn't specify a dimension and put 13 points in curvePoints which became curvePoints[12] with 13 elements from 0-12.
My VB array is creating curvePoints[13] with 14 elements from 0-13 hence the extra 1.
//Create a Point array
Point[] curvePoints = new Point[coords.Length / 2];
Ok and now I rember why I didn't just do it this way in vb in the first place:
Dim curvePoints() As Point = New Point(CInt(coords.Length / 2))
because vb was giving this error:
Error 1 Value of type 'System.Drawing.Point' cannot be converted to '1-dimensional array of System.Drawing.Point'.
and I just figured out why it wanted this
Dim curvePoints() As Point = New Point(CInt(coords.Length / 2)) {}
missed the braces at end!
Actually I just ran through the debugger again and I guess VB array intitializations take the upper bound as alexmoura said.
Since in C# the code above creates an array of 13 points with curvepoints dimension 13 with elements 0-12 whereas the identical VB code creates an array of 14 points with curvepoints 0-13.
I guess I'll have to look more into how VB array initilizations since I thought I knew how they worked.
In previous versions of VB the first element started at 1 not 0 so it's a common mistake to make.
Not to mention the syntax is backwards compared to C#.
Looking at the original C# code I was trying to convert it's easy to see now the problem.
The original C# array didn't specify a dimension and put 13 points in curvePoints which became curvePoints[12] with 13 elements from 0-12.
My VB array is creating curvePoints[13] with 14 elements from 0-13 hence the extra 1.
//Create a Point array
Point[] curvePoints = new Point[coords.Length / 2];
Ok and now I rember why I didn't just do it this way in vb in the first place:
Dim curvePoints() As Point = New Point(CInt(coords.Length / 2))
because vb was giving this error:
Error 1 Value of type 'System.Drawing.Point' cannot be converted to '1-dimensional array of System.Drawing.Point'.
and I just figured out why it wanted this
Dim curvePoints() As Point = New Point(CInt(coords.Length / 2)) {}
missed the braces at end!
Actually I just ran through the debugger again and I guess VB array intitializations take the upper bound as alexmoura said.
Since in C# the code above creates an array of 13 points with curvepoints dimension 13 with elements 0-12 whereas the identical VB code creates an array of 14 points with curvepoints 0-13.
I guess I'll have to look more into how VB array initilizations since I thought I knew how they worked.
Quick comment -
new system.drawing.point(5) -> constructor call
new system.drawing.point(5){} -> array initialization with 6 positions
new system.drawing.point(5) -> constructor call
new system.drawing.point(5){} -> array initialization with 6 positions
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement