Question NaN - Divide by Zero Problem

Cracken

Member
Joined
Sep 30, 2008
Messages
15
Location
England UK
Programming Experience
Beginner
Hi

I have built a small overtime calculator application which works fine, however on some calculations you get an infinity number which just displays infinity as text and not a number.

Could anyone please advise me how to shorten this NaN result to display a number 4 decimal places long and not infinity text.

Thanks for any help in advance.

Code:

Public Class Form1

Dim mth As Single
Dim quart As Single = 1.25
Dim half As Single = 1.5
Dim doub As Integer = 2
Dim hrs As Integer
Dim slr As Integer
Dim ctr As Integer

Private Sub btnCalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate.Click

If txtHours.Text & txtSalary.Text & txtContract.Text = "" Then
lblDetailsError.Text = "Enter overtime hours, gross salary and contract Hours"
ElseIf txtHours.Text & txtSalary.Text = "" Then
lblDetailsError.Text = "Enter number of overtime hours worked and gross salary"
ElseIf txtHours.Text & txtContract.Text = "" Then
lblDetailsError.Text = "Enter number of overtime hours worked and contract hours"
ElseIf txtSalary.Text & txtContract.Text = "" Then
lblDetailsError.Text = "Enter gross salary and contract hours"
ElseIf txtSalary.Text & txtHours.Text = "" Then
lblDetailsError.Text = "Please enter gross salary and overtime hours worked"
ElseIf txtHours.Text = "" Then
lblDetailsError.Text = "Enter number of overtime hours worked"
ElseIf txtSalary.Text = "" Then
lblDetailsError.Text = "Enter the gross salary"
ElseIf txtContract.Text = "" Then
lblDetailsError.Text = "Enter the contract hours"
Else
Convert.ToInt32(txtHours.Text)
Convert.ToInt32(txtSalary.Text)
Convert.ToInt32(txtContract.Text)
lblDetailsError.Text = ""
CheckRate()
End If
End Sub

Private Sub CheckRate()

If rbTimeQuarter.Checked = True Then
CalculateQuart()
ElseIf rbTimeHalf.Checked = True Then
CalculateHalf()
ElseIf rbDoubleTime.Checked = True Then
CalculateDouble()
Else
lblRateError.Text = "Please select an overtime rate"
End If
End Sub

Private Sub CalculateQuart()

hrs = txtHours.Text
slr = txtSalary.Text
ctr = txtContract.Text
mth = slr / 52 / ctr * hrs * quart
txtResults.Text = mth.ToString()
lblRateError.Text = ""
Uncheck()
End Sub

Private Sub CalculateHalf()

hrs = txtHours.Text
slr = txtSalary.Text
mth = slr / 52 / ctr * hrs * half
txtResults.Text = mth.ToString()
lblRateError.Text = ""
Uncheck()
End Sub

Private Sub CalculateDouble()

hrs = txtHours.Text
slr = txtSalary.Text
mth = slr / 52 / ctr * hrs * doub
txtResults.Text = mth.ToString()
lblRateError.Text = ""
Uncheck()
End Sub

Private Sub Uncheck()

If rbDoubleTime.Checked = True Then
rbDoubleTime.Checked = False
ElseIf rbTimeHalf.Checked = True Then
rbTimeHalf.Checked = False
ElseIf rbTimeQuarter.Checked = True Then
rbTimeQuarter.Checked = False
End If
End Sub

Private Sub CloseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseToolStripMenuItem.Click

Me.Close()
End Sub
End Class

Mark
 
This may be what you looking for. Before displaying the number check if its infinity.
VB.NET:
If Double.IsInfinity(yournumber)=True Then 'Display error message End If
 
I completely redid your program code to make it work more efficiently.

First of all, you must place
Option Strict On at the top of your code. This will prevent subtle errors that you may not notice when you make implicit type conversions. I recommend setting all your projects to Option Strict On by selecting it from Tools/Options/Projects and Solutions/Vb Defaults.

Secondly, all your variable should be declared as Double, not as Single or Integer, except the mth variable, which should be declared as Decimal. This will eliminate the Infinity problem.

Use the TryParse method for converting text to numbers. This will prevent errors in case your user enters a non-numeric value or leaves the textbox blank. TryParse returns a Boolean value, so if it's False, it means the input was wrong. You can also use it to assign a value to a variable. If the textbox is numeric, it will return the correct number to the variable. If it's blank or incorrect, it will return 0 instead of an error.

I used a For-Each block to test for correct input in the three textboxes. A MessageBox will direct the user back to the appropriate textbox to input the correct value. A MessageBox also alerts the user to select a radio button. I then used a Select Case block to compute the results. The result is output with a string format. ToString("0.0000") displays it with 4 decimal places. If you use ToString("C") it will display as currency with a $ sign and 2 decimal places.

To uncheck the radio buttons, all you need to do is make one of them True, which makes all the rest False, and then make the True one False.

Here is the complete code. Please try it out and let me know if you were able to implement it into your program.



VB.NET:
Option Strict On

Public Class Form1
	Dim mth As Decimal
	Dim quart As Double = 1.25
	Dim half As Double = 1.5
	Dim doub As Double = 2
	Dim hrs As Double
	Dim slr As Double
	Dim ctr As Double

	Private Sub btnCalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate.Click
		Dim entry As String = ""
		Dim d As Double
		For ndx As Integer = 0 To Controls.Count
			For Each ctl As Control In Controls
				If TypeOf ctl Is TextBox And ctl.TabIndex = ndx Then
					If Double.TryParse(ctl.Text, d) = False Then
						ctl.Text = ""
						Select Case ctl.Name
							Case "txtHours"
								entry = "overtime hours."
							Case "txtSalary"
								entry = "gross salary."
							Case "txtContract"
								entry = "contract hours."
							Case Else
								entry = ""
						End Select
						If entry <> "" Then
							MessageBox.Show("You must enter your " & entry)
							ctl.Focus()
							Exit Sub
						End If
					End If
				End If
			Next ctl
		Next ndx
		Double.TryParse(txtHours.Text, hrs)
		Double.TryParse(txtSalary.Text, slr)
		Double.TryParse(txtContract.Text, ctr)
		CheckRate()
	End Sub

	Private Sub CheckRate()
		If rbTimeQuarter.Checked = False And rbTimeHalf.Checked = False And rbDoubleTime.Checked = False Then
			MessageBox.Show("Please select an overtime rate")
		Else
			Select Case True
				Case rbTimeQuarter.Checked
					mth = Convert.ToDecimal(slr / 52 / ctr * hrs * quart)
				Case rbTimeHalf.Checked
					mth = Convert.ToDecimal(slr / 52 / ctr * hrs * half)
				Case rbDoubleTime.Checked
					mth = Convert.ToDecimal(slr / 52 / ctr * hrs * doub)
			End Select
			txtResults.Text = mth.ToString("0.0000")	'4 decimal places
			'txtResults.Text = mth.ToString("c")		'currency with $ and 2 decimal places
			rbDoubleTime.Checked = True
			rbDoubleTime.Checked = False
		End If
	End Sub

End Class
 
Last edited:
I would use NumericUpDown control for numeric input instead of TextBox.
 
Back
Top