Multiple types of return values

kreeben
12-14-2004, 03:03 AM
This question has to do with strict declaration of data types and how to handle situations where a function returns one object type if successful or another type if unsuccessful. I would like to know how the pros handle the following scenario:



Private sum As int16
sum = Divide(1, 0)
If Not sum Then
MessageBox.Show("What kind of stunt are you trying to pull here?")
End If

Private Function Divide(ByVal num1 As Int16, ByVal num2 As Int16) As Double
Dim _sum As Double
Try
_sum = num1 / num2
Return _sum
Catch ex As Exception
Return False
End Try
End Fuction


This code probably wont work, for two reasons. To start, the variable sum is declared as an integer so it cant possibly have a boolean value. Secondly, the function Divide is declared as Double, so it cant possibly return a Boolean.

What is the best way to handle these kinds of situations?

Himo
12-14-2004, 03:17 AM
You can return 0, because a division will never return 0 exactly.

Faith
12-14-2004, 04:15 AM
Hi!
The only case of scenario wherein the error will occur is when your dividing number is zero, So let's just decide if it is zero, then it's an certain error, and thus we prevent having to test for the division itself, which won't even hit the performance.

Private Function Divide(ByVal num1 As Int16, ByVal num2 As Int16) As Double
If num2 = 0 Then
Return 0
'Throw New System.ArithmeticException("Division by zero error")
Else
Return num1 / num2
End If
End Function


But as another thing I'd like to say here is the commented part in that code, as it were my manual throwing of a nasty arithmetic exception, as it works as an excellent gateway to say something about error handling...

As you can probably notice; that is the syntax to throw a new exception, but wait, it has no error handler, right.

So what's the important part here is the thing called unwinding the stack, let's explain some of this...

Sub A calls Function B, which would Call Function C,
So if Sub A was the only one of these three that would encaspulate an error handler, then the error thrown in Function C, would unwind from Function C, to Function B, and if no error handler there, then to Sub A, and if no error handler there either, then crash,boom...

So,
if you were to call that function there with this syntax from another sub:

Try
Divide(1, 0)
Catch ex As Exception
MsgBox(ex.Message)
End Try

The Divide function would virtually return an arithmetic exception with the message "Division by zero error". This is a very organized way of doing it,
however, the throwing and catching and unwinding will take a lot longer than actually returning zero as said in the post before, and then checking if the returned number is zero and then perhaps a messagebox is displayed... If you test these two options you will notice the performance difference...

I thought If you didn't know about error handling so much this might just be useful to know, for future reference at least...

AtmaWeapon
12-14-2004, 08:20 AM
Look at how Double.TryParse works for your inspiration. You declare one of the parameters as ByRef so that it will hold any value, but return True or False to indicate failure. This is and has always been the easiest way to have multiple return types. (The other ways are to return Object which breaks your type safety or to return a class type with a failure flag, which is just more overhead).

Private sum As int16
If Not Divide(1, 0, sum) Then
MessageBox.Show("What kind of stunt are you trying to pull here?")
End If

Private Function Divide(ByVal num1 As Int16, ByVal num2 As Int16, ByRef result As Double) As Boolean
Dim _sum As Double
Try
result = num1 / num2
Return True
Catch ex As Exception
result = 0
Return False
End Try
End Fuction

Also note that result should technically be of type Int16. You run a very serious risk of loss of data. Type Double is a 64-bit variable (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vadatDouble.asp), and depending on how the data is stored chopping off the last 48 bits could give you incorrect results. Why are you using Int16 in the first place?

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum