Convert String to int16 - vb.net

I faced a "ridiculous" problem.
I was trying to convert a string to int16 (I am forced to do it in int16 and not in int32/integer).
My first thought was to try:
convertedVal = Convert.ToInt16(newVal)
which thrown an exception: Value was either too large or too small for UInt16.
But my string was "10", so it was between the minValue and the maxValue.
I solved my problem using :
convertedVal = Int16.Parse(newVal) 'TryParse works also
Although I solved my problem I haven't understand what I did wrong.
Could somebody explain to me why this happened?
Thanks for your time

This usually happens if there is an extra space on the string, so better Trim it
convertedVal = Convert.ToInt16(newVal.Trim())

Both methods should be the same according to the MSDN page
Using the ToInt16(String) method is equivalent to passing value to the Int16.Parse(String) method. value is interpreted by using the formatting conventions of the current thread culture.

Where do you get this string?
If it comes from user input I wouldn't trust much that he/she types a correct int16 value to use a Convert or Parse method.
using TryParse leads to a more robust code.
Dim result as Short
Dim newVal as String = "10 sadaas"
if Int16.TryParse(newVal, result) = False then
result = 0
end if

Related

CStr() vs. Str() vs. .ToString()

I want to know what exactly are the differences between CStr(), Str() and .ToString()?
Label1.Text = CStr(Int(Rnd() * 10))
and
Label1.Text = Str(Int(Rnd() * 10))
and
Label1.Text = Int(Rnd() * 10).ToString
If I use this condition:
If Label1.Text = "7" Then
'Some code here
End If
Str() doesn't work here. What's the difference?
ToString will call the .ToString() function on a particular instance.
In practice, this means that it will throw an exception if the object in
question is Nothing. However, you can implement .ToString() in your own
classes to get a useful string representation of your object, whereas
CType/CStr only work with built-in classes and interfaces.
CStr and CType(expression, String) are exactly equivalent (I'm not
sure where the other poster got the idea that CStr is faster). But they
aren't really functions, they're compiler directives that will emit very
different code depending on the declaration of expression. In most
cases, these directives call a bunch of internal VB code that tries to
get a reasonable string out of expression.
DirectCast(expression, String) assumes that the expression in
question really is a String and just casts it. It's the fastest of all
these options, but will throw an exception if expression is anything
other than a String.
As an Addition to the VBA/VB6 Environment where we have no ToString():
Str() is not aware of international representation. The decimal separator always is a dot (.).
As already mentioned above it prefixes the resulting string with a blank in case of positive values.
There also exists Str$(). The difference to Str() is the return type:
Str() returns a variant of type string, Str$() returns a string.
And Str$() is slightly faster then Str().
CStr() in contrast is aware of international representation. The decimal separator depends on the Windows international settings.
No additional prefixing for positive values will be done.
So if you need to convert a value type to a string and have to ensure a dot as a decimal separator and no prefixing blank, then use this syntax:
Dim d As Double
d = 123.456
Dim s As String
s = Trim(Str$(d))
I don't know about ToString() and i don't know about VB.NET
But in VB6 (Visual Basic 6):
Both of Cstr() and Str() converts values to string. but Cstr() is better because:
Str(): After converting to string it adds 1 space before positive numbers. for example: Str(22) > " 22"
Cstr(): After converting to string it never adds the above extra space - For best result use it with Trim() - Trim(Cstr(Variable))
Although not a problem in the code in the question, it is important to mention that Str() only converts numerical expressions to string, gives an error in other cases, so don't use it for converting values of a cell.
My answer is str() is evil as it always prepends a space for the sign character so if you are comparing values it fails. Instead use CStr() instead which does not do this.
You may comes across business logic that tries to do this:
Eg:
Dim sVar as String = "1"
Dim i as Integer = 1
console.write( cstr(i) = sVar )
Which outputs:
False
I lost a couple hours on this one as the code was quite deep in old code and was very difficult to grok in production environment where logging based debugging was all that was available.

Double or integer? What to use with BIG or SMALL data types?

I have a value of: "2.54334881002458E-37" and i keep getting "overflow" exception when i'm using a double.
what should i use to make this work?
Thank you
code snippet:
Dim curries, act, cat As Double
For Each dataRow As DataRow In dt.Rows
curries = dataRow("Activity")
getting the error when i try to assign Activity to curries.
but "activity" is a string in the database....
Double is already 64 bits worth of floating point number.
Can you post code where you are getting this overflow?
Decimal might be worth a shot, but you have to post code so that we can understand the issues you are encountering.
Based on your edit in your post, why are you storing numbers as strings in your database? That is a definite no no...unless you are not doing any sort of arithmaetic operation only then can you store them as varchar / string.
Give us a sample of what the data looks like...I think your issue stems from not converting the string to a decimal, if activity is a string convert it using DirectCast or CType (cast the value):
curries = CType(datarow("Activity"), Double)
Change your unit of measure, so that you're not working in 10^-37 of whatever it is you're dealing with. This problem just screams "I'm not solving this in the appropriate domain."
According to MSDN, Double should have no problem at all with your number:
Range:
-1.79769313486231570E+308 through -4.94065645841246544E-324 † for negative values;
4.94065645841246544E-324 through 1.79769313486231570E+308 † for positive values
and if the need to have large numbers and precise I suggest the use of decimal numbers, more information here.
http://msdn.microsoft.com/en-us/library/system.decimal.aspx
Bye

How to convert Boolean type into "ON" "OFF" using String.Format

Is there are any way to convert Boolean type into "ON"/"OFF" using string formatter, like:
Dim inpValue as Boolean
Dim outValue = String.Format("0:ON;OFF", inpValue)
' should show OFF as output
without code or IFormatProvider?
What is wrong with:
Dim inpValue as Boolean
Dim outValue = If(inpValue, "ON", "OFF")
Here's a crazy trick from another question but it's completely unreadable. I strongly advise you not to do this! If you are of nervous disposition, stop reading now.
String.Format("{0:ON;ON;OFF}", CDbl(inpValue))
This converts the Boolean to -1 or 0 and then uses a custom numeric format.
This should help you:
http://www.developmentnow.com/g/38_2004_4_0_0_238356/iformatprovider-for-boolean.htm
There isn't any built-in support that I am aware of. However, depending on how much control you have, you can create your own format provider (IFormatProvider). Here is a link to a discussion on this: bool format provider.
You can't do this using String.Format (without implementing IFormatProvider which seems like a overkill for your purposes), but you can do it in one line using IIf:
IIf(inpValue, outValue=True, outValue=False)
Personally, I recommend using an If/Else statement instead of IIf, as IIf is not intuitive for some programmers coming from other languages.
c# - not the most elegant but effective:
string outValue = inpValue.ToString().Replace("False", "OFF").Replace("True", "ON");

Check for only digits in VB.NET String

I want to run a check on a String right before I append it to a StringBuilder to make sure only numeric characters are in the string. What's a simple way to do that?
Use Integer.TryParse() it will return true if there are only digits in the string. Int32 max value is 2,147,483,647 so if your value is less then that then your fine.
http://msdn.microsoft.com/en-us/library/f02979c7.aspx
You can also use Double.TryParse() which has a max value of 1.7976931348623157E+308 but it will allow a decimal point.
If your looking to get the value that isnt an integer you can always go through the string one at a time
string test = "1112003212g1232";
int result;
bool append=true;
for (int i = 0; i < test.Length-1; i++)
{
if(!Int32.TryParse(test.Substring(i,i+1),out result))
{
//Not an integer
append = false;
}
}
If append stays true then the string is an integer. Probably a more slick way of doing this but this should work.
Coding in VB.Net to check whether a string contains only numeric values or not.
If IsNumeric("your_text") Then
MessageBox.Show("yes")
Else
MessageBox.Show("no")
End If
Use regular expressions:
Dim reg as New RegEx("^\d$")
If reg.IsMatch(myStringToTest) Then
' Numeric
Else
' Not
End If
UPDATE:
You could also use linq to accomplish the same task if you're doing it in VB.Net 2008/2010.
Dim isNumeric as Boolean = False
Dim stringQuery = From c In myStringToTest
Where Char.IsDigit(c)
Select c
If stringQuery.Count <> myStringToTest.Length Then isNumeric = False
If you do not wish to use RegEx, a simple check on each character with char.IsNumber works.
You can combine it with the All extension method (in C#, I don't know how to write it in VB.net):
string value = "78645655";
bool isValid = value.All(char.IsNumber);
Check out other char method, like IsDigit.
2 other compact solutions :
Without LINQ :
Dim foo As String = "10004"
Array.Exists(foo.ToCharArray, Function(c As Char) Not Char.IsNumber(c))
With LINQ (just VB.Net equivalent of the C# version in another answer) :
foo.All(Function(c As Char) Char.IsNumber(c))
Negative values haven't been mentioned, which Integer.TryParse would accept.
I prefer UInteger.TryParse which will reject a negative number. However, there is an additional check required in case the value starts with "+":
Dim test As String = "1444"
Dim outTest As UInteger
If Not test.StartsWith("+") AndAlso UInteger.TryParse(test, outTest) Then
MessageBox.Show("It's just digits!")
End If
or ULong.TryParse for a larger number.
Pattern matching! See this, this (about.com) and this (VB.NET dev article).
You can use regular expression or Integer.TryParse and I prefer the regular expression check
Presuming you're looking at relatively short strings which will never have a number greater than the Max Int32 value, use Gage's solution. If it's a variable length and sometimes you could overflow, use Regex (System.Text.RegularExpressions)
The regex for checking against just numbers is fairly routine: ^[0-9]+$
Check here for a very good explanation of Regex.

testing if a string can be cast as a integer in VB.NET

Is there a better way of testing if a string can be converted to an integer other than something like the following?
Public Function IsInt(ByVal value As Object) As Boolean
Try
Dim temp As Integer = CInt(value)
Return True
Catch ex As Exception
Return False
End Try
End Function
by "better" I mean less verbose and/or w/o an exception.
TryParse would be the way to go, but I'm using the compact framework 2.0 and tryparse doesn't seem to be implemented....
Thanks anyways.
It seems that MarkJ is correct and the above seems to be functionally the same as IsNumeric, so I suppose that's my answer. I don't know why I thought CInt was more strict than IsNumeric. I guess it's better to test using CInt verses IsNumeric since that's the function I'm using to do the conversion?
You can use the built in IsNumeric Function
Dim CanConvert as Boolean = IsNumeric(value)
http://msdn.microsoft.com/en-us/library/6cd3f6w1(VS.71).aspx
Since TryParse isn't supported on the Compact Framework, regex is your next best option.
The first example doesn't allow decimals. The second one does.
Regex.IsMatch(value, "^-?\d+$")
Regex.IsMatch(value, "^-?\d+(?:\.\d+)?$")
If you need to allow for scientific notation, you need to tweak it a little more. It really just isn't that bad. You've got the beginning of the string ^, an optional dash -?, one or more digits \d+, a non-capturing group (?:) that looks for a single decimal point \. and one or more digits \d+. Another ? to allow either zero or one instances of the non-capturing group, and then the end of the string $.
Edit:
One thing I didn't think about before: this method is a little imprecise because you could get a really huge number that is numerically a valid integer but can't be converted to an Int32. If that's a possibility, you could constrain the number of characters. Instead of \d+, you could do \d{1,8}, for example.
Public Function IsInt(ByVal value As Object) As Boolean
Dim i As Integer
Return Integer.TryParse(Convert.ToString(value), i)
End Function
you can use Integer.TryParse, which will return a bool indicating whether the conversion was successfull or not
well if you want to avoid using exceptions you could match it against a regular expression that allows only digit characters before converting.
If you're only performing the conversion infrequently, what you have is fine (assuming there's no TryParse() available to you) - it's not going to affect performance.
If you're going to perform millions of conversions, and a large number of them might fail then the exception you're catching could be a perf issue (maybe).
If you can't use TryParse() probably the best thing to do (perf-wise) is to simply check each character in the string and if it's not a digit return false. Don't forget to account for a possible negative sign and group separators (if you want to support them).
Otherwise, parse the string to an int, which will succeed in 99% of the cases. you'll only get an exception if it won't fit. If you really want to avoid the exception that Parse() might generate, it's not hard to actually parse the sting of digits yourself, and return failure if it goes out of range.
Jon Skeet did a quick analysis of this back before the Framework contained TryParse():
Checking if a string can be converted to Int32
None of this fixes the verbosity, though. but as long as it's a self-contained method, there's no real problem with a little verbosity.
Dim s as String = "23"
Dim i as Integer
If Int32.TryParse(s, i) Then
' String was a valid integer... '
End If
Use the TryParse shared method of the Integer type.
For example:
Private Function CanStringBeCastAsInteger(ByVal myString As String) As Boolean
Dim myInt As Integer = 0
Return Integer.TryParse(myString, myInt)
End Function
The benefit of using the TryParse method is that it avoids having to throw and subsequently catch an Exception when the cast fails. Throwing and catching exceptions is an expensive operation.
Not only will the TryParse method return a True/False result, telling you if the conversion will succeed or not, it will also return, in the myInt parameter in my example, the resulting conversion for you, all in one line of code.
Here is something very similar to what you have already but uses the Convert class instead of CType and does not use TryParse
Public Function IsInt(ByVal value As Object) As Boolean
Try
Convert.ToInt32(value)
Return True
Catch ex As System.FormatException
Return False
End Try
End Function
You'd need to roll your own regex e.x.: Regex.IsMatch("4354354", "\d+"), and still include the try/catch block as a backup.
Do as follow
If myString <> "" And IsNumeric(myString) = True Then
If CDbl(myString) - Int(CDbl(myString)) > 0 Then
.... myString is integer
End If
End If