VB.NET OverflowException was unhandled - vb.net

I have a problem in VB 2008 that gives me an error: " OverflowException was unhandled. "
in that piece of code: The error is highlights the Next b
Dim gfx As Graphics
Dim a,r,g,b As byte
Dim left As Integer
Dim lStep As Integer = 1
For left = 0 To Me.ClientRectangle.Height Step lStep
For a = 1 To 255
For r = 1 To 255
For g = 1 To 255
For b = 1 To 255
gfx.DrawLine(New Pen(Color.FromArgb(a, r, g, b)), 0, left, Me.ClientRectangle.Width, left)
Next b
Next g
Next r
Next a

Dim a,r,g,b As byte
That's where your problem started. Your For loops increment from 1 to 255, stopping when the value reaches 256. But that is not possible for a Byte, it can only store a value between 0 and 255. Kaboom when the Next statement tries to increment it from 255 to 256.
Simply declare them As Integer. It not only solves the overflow problem, it is also faster.

Related

Factorial function returning squared number and not factorial

Where is my code wrong? It is returning the square of any number:
Sub factorial()
Dim x As Long, i As Integer, fact As Long
x = InputBox("enter the integer")
For i = 1 To x
fact = i * x
Next i
MsgBox fact
End Sub
Practicing Loops and If Statements!?
Option Explicit
' If you are practicing (loops) then:
Sub factorial()
Dim x As Long, i As Long, fct As Double
x = InputBox("enter the integer")
If x >= 0 And x <= 170 Then
fct = 1
If x > 1 Then
For i = 2 To x
fct = fct * i
Next i
End If
MsgBox fct
Else
MsgBox "Next time enter a number between 0 and 170."
Exit Sub
End If
End Sub
' ...if not, just use Fact
Sub factorialExcel()
Dim x As Long
x = InputBox("enter the integer")
If x >= 0 And x <= 170 Then
MsgBox Application.WorksheetFunction.Fact(x)
Else
MsgBox "Next time enter a number between 0 and 170."
Exit Sub
End If
End Sub
One mistake is that fact needs to be initialized with fact=1 before it is used in the loop. Then inside the loop the result is should be multiplied by the iteration number, as in fact = fact * i. Lastly to make sure you get the highest possible range use the LongLong type (available in VB7 and above) which is a 64-bit integer. Oh, and don't forget to convert the text returned by InputBox to a number type.
Sub factorial()
Dim x As Long, i As Long, fact As LongLong
x = CLng(InputBox("enter the integer"))
fact = 1
For i = 1 To x
fact = fact * i
Next i
MsgBox fact
End Sub
PS. Never use Integer in VBA, but rather opt for the native 32-bit integer Long.
In your code the value of fact is recalculated on any iteration and it is not kept. So at the end, just the last value is shown, which is x*i where i=x, e.g. a square of the input. Something like this, using 90% of your code works:
Sub Factorial()
Dim x As Long, i As Long, fact As Long
x = 5
fact = 1
For i = 1 To x
fact = fact * i
Next i
Debug.Print fact
End Sub

Does this code not work because it will take a long time or is it broken?

I am currently trying to generate random numbers until a user defined amount of identical numbers in a row appears. The numbers range from 1 to 10.
When I want 8 identical numbers in a row it takes between 3 and 5 seconds. It goes through about 5 million random numbers. When I want 9 in a row I have left it for over 45 minutes without any luck.
I thought it would only take about 10 times the amount of time as it did for 8 since 1/10 to the power of 9 is only ten times bigger than to the power of 8.
Is it a problem with my code or have I messed up the maths?
MY CODE:
Sub Main()
Console.WriteLine("how many identical numbers in a row do you want")
Dim many As Integer = Console.ReadLine
Dim storage(many - 1) As Integer
Dim complete As Boolean = False
Dim part As Integer = 0
Dim count As Integer = 0
Randomize()
While complete = False
count += 1
storage(part) = Int(Rnd() * 10) + 1
' Console.WriteLine(storage(part))
part += 1
If part = many Then
part = 0
End If
If storage.Min = storage.Max Then
complete = True
End If
End While
Console.WriteLine("===========")
Console.WriteLine(count.ToString("N"))
Console.WriteLine("===========")
For i = 0 To many - 1
Console.WriteLine(storage(i))
Next
Console.ReadLine()
End Sub
There is more than one possibility: it could be that the VB Rnd function is written so that it can never work, or it could be that it really does simply take a long time sometimes. You would have to do many trials and average them out to find out if your expected ratio of 1:10 works as expected.
Incidentally, you don't need to keep the last ten numbers. You can just keep a count of how many times the next random number equals the previous number. Also I suggest trying a different RNG (random number generator), for example the .NET one:
Module Module1
Dim rand As New Random()
Sub Main()
Console.Write("How many identical numbers in a row do you want: ")
Dim howMany As Integer = CInt(Console.ReadLine)
Dim count As Long = 0
Dim previous = -1
Dim soFar = 0
Dim n = 0
While soFar < howMany
count += 1
n = rand.Next(1, 11)
'Console.Write(n.ToString() & " ")
If n = previous Then
soFar += 1
Else
'If previous >= 0 Then
' Console.WriteLine(" X")
' Console.Write(n.ToString() & " ")
'End If
previous = n
soFar = 1
End If
End While
Console.WriteLine()
Console.WriteLine("Tries taken: " & count.ToString())
Console.ReadLine()
End Sub
End Module

Optimization of matrix multiplication in vb.net

I'm currently trying to do some work on a neural network class in visual basic. My main drag at the moment is the multiplication of the matrices is so slow! Here's the code I use right now;
Public Function MultiplyMatricesParallel(ByVal matA As Double()(), ByVal matB As Double()()) As Double()()
Dim matACols As Integer = matA(0).GetLength(0)
Dim matBCols As Integer = matB(0).GetLength(0)
Dim matARows As Integer = matA.GetLength(0)
Dim result(matARows - 1)() As Double
For i = 0 To matARows - 1
ReDim result(i)(matBCols - 1)
Next
Dim tempMat()() As Double = MatrixTranspose(matB)
Parallel.For(0, matARows, Sub(i)
For j As Integer = 0 To matBCols - 1
Dim temp As Double = 0
Dim maA() As Double = matA(i)
Dim maB() As Double = tempMat(j)
For k As Integer = 0 To matACols - 1
temp += maA(k) * maB(k)
Next
result(i)(j) += temp
Next
End Sub)
Return result
End Function
I just jagged arrays as they are quicker in vb than rectangular arrays. Of course they really are rectangular otherwise the matrix multiplication wouldn't work (or make sense). Any advice/help would be appreciated, for reference the matrix size can change but it's currently around 7,000 x 2,000 at the maximum.

pascal triangle gives overflow for 13

I wrote a code to output Pascal triangle in a multi-line textbook. The program works fine for inputs between 1 to 12 but gives an overflow error once a value of 13 is inputed.
Is there any modifications I can make to enable the program to accurately give outputs for 13 and higher?
Here is the code I used:
Public Class pascal_triangle
Private Function factorial(ByVal k As Integer) As Integer
If k = 0 Or k = 1 Then
Return 1
Else
Return k * factorial(k - 1)
End If
End Function
Private Sub BtnGen_Click(sender As Object, e As EventArgs) Handles BtnGen.Click
Dim nCr As Integer
Dim i, j, k As Integer
Dim output As String
output = ""
j = Val(TxtColumn.Text)
For k = 0 To j
For i = 0 To k
Dim fact, fact1, fact2 As Integer
fact = factorial(k)
fact1 = factorial(k - i)
fact2 = factorial(i)
nCr = fact / (fact1 * fact2)
TxtOutput.Text += Str(nCr) & output
Next
TxtOutput.Text += vbCrLf
Next
End Sub
End Class
The overflow is because 13! is too big to fit in an integer.
The largest representable integer (32-bit signed) is
2147483647 (0x7FFFFFFF == 01111111 11111111 11111111 11111111b)
so :
12! = 479001600
MaxInt = 2147483647
13! = 6227020800
If you want to use larger numbers than this you need to use a larger number type. The next larger types are Long (64-bit signed, max 9223372036854775807) or, for your purposes, ULong (unsigned 64-bit, since you don't need negative numbers, which is twice that at 18446744073709551615).
This will let you calculate up to20!, which is 2432902008176640000. For numbers larger than this you will need to look into using either BigInteger or other dedicated libraries that allow for holding and calculating arbitrarily large numbers.
Alternatively, you can look into other methods of computing an arbitrary row without using factorials.
Your main problem is that you are using Integer which is too small to hold the factorial of 13. Change your Factorial function to return Long. It would also be a good idea to turn Option Strict On and make nCr a Double.
Private Function factorial(ByVal k As Integer) As Long
If k = 0 Or k = 1 Then
Return 1
Else
Return k * factorial(k - 1)
End If
End Function
Private Sub BtnGen_Click(sender As Object, e As EventArgs) Handles BtnGen.Click
Dim nCr As Double
Dim i, j, k As Integer
Integer.TryParse(TxtColumn.Text, j)
For k = 0 To j
For i = 0 To k
Dim fact, fact1, fact2 As Long
fact = factorial(k)
fact1 = factorial(k - i)
fact2 = factorial(i)
nCr = fact / (fact1 * fact2)
TxtOutput.Text += nCr.ToString & " "
Next
TxtOutput.Text += vbCrLf
Next
End Sub

vb.net - Generating number 0 to N, puts in array, and it my program freezes

I want to randomly generate numbers between 0 to 5 and put them in array(with 6 size) but when the randomly generated number is 0 it skips so leaving my array only has 1 to 5, and it just generates infinitely finding other numbers beside 1 to 5, which absolutely result to freeze coz im just randomizing only from 0 to 5.
heres my code, i know the GoTo is 'oldschool and harmful' to coding based on my research, but just disregard it(or if u have better coding then feel free to revise my code XD):
Dim intNumber As Integer
Dim xP, yP As Integer
'no period repeat
For xP = 0 To 5
If arrPeriod(xP) = Nothing Then '<--- this is why it does not include 0 to the array, making 0 equals to Nothing
Start:
intNumber = GetRandom(0, 6)
For yP = 0 To 5
If intNumber = arrPeriod(yP) Then
GoTo Start
End If
Next yP
arrPeriod(xP) = intNumber
End If
Next xP
with simulation that code will give me this result, e.g.
arrPeriod() = {1, 5, 4, 3, 2, ...infinite loop/freeze}
what I want is this
arrPeriod() = {5, 3, 2, 4, 1, 0}
Instead of populating the array with random numbers,
populate it with all possible numbers and sort it in a random order. Using Linq it can be done in the same row:
Dim r As New Random
Dim arrPeriod As Integer() = Enumerable.Range(0, 6).OrderBy(Function() r.Next).ToArray()
Fiddle here
I think you might have a problem with your index going from 0 to 5 in both loops.
Try this:
Dim A() As Integer
ReDim A(5)
A(0) = CInt(Floor(6 * Rnd()))
For i As Integer = 0 To 4
choose: Dim value As Integer = CInt(Floor(6 * Rnd()))
For j As Integer = 0 To i
If value = A(j) Then GoTo choose
Next
A(i) = value
Next