Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IsNumeric returns true for strings containing a D character

I had a strange error in a VB6 app this morning and it all stems from the fact that IsNumeric is not working as I expected. Can someone shed some light on why? To me this seems like a bug.

This code displays 4.15877E+62 in a message box:

Dim strMessage As String
strMessage = "0415877D57"
If IsNumeric(strMessage) Then
    MsgBox CDbl(strMessage)
Else
    MsgBox "not numeric"
End If

I am guessing that the runtime engine is incorrectly thinking that the D is in fact an E? I think this is a bug though as the exact same code in VB.NET outputs not numeric Is this a known issue with IsNumeric?

like image 506
Matt Wilko Avatar asked Nov 25 '11 09:11

Matt Wilko


2 Answers

If you check the VB6 docs:

Note Floating-point values can be expressed as mmmEeee or mmmDeee, in which mmm is the mantissa and eee is the exponent (a power of 10). The highest positive value of a Single data type is 3.402823E+38, or 3.4 times 10 to the 38th power; the highest positive value of a Double data type is 1.79769313486232D+308, or about 1.8 times 10 to the 308th power. Using D to separate the mantissa and exponent in a numeric literal causes the value to be treated as a Double data type. Likewise, using E in the same fashion treats the value as a Single data type.

like image 129
Bob77 Avatar answered Nov 04 '22 11:11

Bob77


I've been using my own IsNumber function for a long time exactly because of this situation. IsNumeric can also return true for certain money symbols, like this: IsNumeric("$34.20").

My IsNumber function looks like this:

Public Function IsNumber(ByVal Data As String) As Boolean

  If Data = "" Then
    IsNumber = False
    Exit Function
  End If

  IsNumber = IsNumeric(Data & "e0")

End Function

The idea here is... if there is already an e or d in the data, adding another will cause the data to NOT be numeric using the IsNumeric check. You can easily change this function to only allow for integers by replacing "e0" with ".0e0". Want just positive integers? then use this: IsNumeric("-" & Data & ".0e0")

The only downside of this method is that an empty string normally is not numeric, but when you append "e0" to it, it becomes numeric so you need to add a check for that, like I did in my code.

like image 14
George Mastros Avatar answered Nov 04 '22 11:11

George Mastros