I have a variable that holds a string "02100030000000000000000000D5010008D501000804" and I'm byte separating the string using
For i As Integer = 1 To (stringReader.Length - 1) Step 2
'Get the successive 2-character substrings, parse as bytes and add to total
Dim b As Byte = Byte.Parse(stringReader.Substring(i, 2), NumberStyles.AllowHexSpecifier)
sum = sum + CInt(b)
Next
I'm converting the strings to direct integers.e.g:(string"10" to Integer10 and ). That works fine. But Whenever I convert the string"02" to Integer, I get only Integer(2) and I need Integer(02). How can I proceed with?
My code is:
stringReader = fileReader.ReadLine()
byt = stringReader(1) + stringReader(2)
stringreader contains something like "100030000000000000000000D5010008D501000804"
Byte separation
For i As Integer = 1 To (stringReader.Length - 1) Step 2
'Get the successive 2-character substrings, parse as bytes and add to total
Dim b As Byte = Byte.Parse(stringReader.Substring(i, 2), NumberStyles.AllowHexSpecifier)
sum = sum + CInt(b)
Next
You can use
number.ToString("D2")
where number is an integral type like System.Int32(Integer).
Further reading: Standard Numeric Format Strings: The Decimal ("D") Format Specifier
If you have a String instead you could also use String.PadLeft:
"2".PadLeft(2, "0"c) ' -> "02"
Related
I'm trying to split a string of 32 numerical characters into a 16 length Array of Byte and each value has to stay numerical
from "70033023311330000000004195081460" to array {&H_70, &H_03, &H_30, &H_23, ..}
I've tried multiple stuff but each time either it's the conversion that's wrong or I can't find the appropriate combination of functions to implement it.
'it splits but per 1 character only instead of two
str.Select(Function(n) Convert.ToByte(n, 10)).ToArray
'I also tried looping but then the leading zero disappears and the output is a string converted to HEX which is also not what I want.
Function ConvertStringToHexBinary(str As String) As Byte()
Dim arr(15) As Byte
Dim k = 0
For i As Integer = 0 To str.Length - 1
arr(k) = str(i) & str(i + 1)
k += 1
i += 1
Next
Return arr
End Function
Anyone got any suggestion what to do?
G3nt_M3caj's use of LINQ might be.. er.. appealing to the LINQ lovers but it's horrifically inefficient. LINQ is a hammer; not everything is a nail.
This one is about 3 times faster than the LINQ version:
Dim str As String = "70033023311330000000004195081460"
Dim byt(str.Length/2) as Byte
For i = 0 to str.Length - 1 Step 2
byt(i/2) = Convert.ToByte(str.Substring(i, 2))
Next i
And this one, which does it all with math and doesn't do any new stringing at all is just under 3 times faster than the above (making it around 9 times faster than the LINQ version):
Dim str As String = "70033023311330000000004195081460"
Dim byt(str.Length / 2) As Byte
For i = 0 To str.Length - 1
If i Mod 2 = 0 Then
byt(i / 2) = (Convert.ToByte(str(i)) - &H30) * &HA
Else
byt(i / 2) += Convert.ToByte(str(i)) - &H30
End If
Next i
Of the two, I prefer the stringy version because it's easier to read and work out what's going on - another advantage loops approaches often have over a LINQ approach
Do you need something like this?
Dim str As String = "70033023311330000000004195081460"
Dim mBytes() As Byte = str.
Select(Function(x, n) New With {x, n}).
GroupBy(Function(x) x.n \ 2, Function(x) x.x).
Select(Function(y) Convert.ToByte(New String(y.ToArray()), 10)).ToArray
I'm using this query in vb.net
Raw_data = Alltext_line.Substring(Alltext_line.IndexOf("R|1"))
and I want to increase R|1 to R|2, R|3 and so on using for loop.
I tried it many ways but getting error
string to double is invalid
any help will be appreciated
You must first extract the number from the string. If the text part ("R") is always separated from the number part by a "|", you can easily separated the two with Split:
Dim Alltext_line = "R|1"
Dim parts = Alltext_line.Split("|"c)
parts is a string array. If this results in two parts, the string has the expected shape and we can try to convert the second part to a number, increase it and then re-create the string using the increased number
Dim n As Integer
If parts.Length = 2 AndAlso Integer.TryParse(parts(1), n) Then
Alltext_line = parts(0) & "|" & (n + 1)
End If
Note that the c in "|"c denotes a Char constant in VB.
An alternate solution that takes advantage of the String type defined as an Array of Chars.
I'm using string.Concat() to patch together the resulting IEnumerable(Of Char) and CInt() to convert the string to an Integer and sum 1 to its value.
Raw_data = "R|151"
Dim Result As String = Raw_data.Substring(0, 2) & (CInt(String.Concat(Raw_data.Skip(2))) + 1).ToString
This, of course, supposes that the source string is directly convertible to an Integer type.
If a value check is instead required, you can use Integer.TryParse() to perform the validation:
Dim ValuePart As String = Raw_data.Substring(2)
Dim Value As Integer = 0
If Integer.TryParse(ValuePart, Value) Then
Raw_data = Raw_data.Substring(0, 2) & (Value + 1).ToString
End If
If the left part can be variable (in size or content), the answer provided by Olivier Jacot-Descombes is covering this scenario already.
Sub IncrVal()
Dim s = "R|1"
For x% = 1 To 10
s = Regex.Replace(s, "[0-9]+", Function(m) Integer.Parse(m.Value) + 1)
Next
End Sub
I want to split my long array to 2bytes (4 digit HEX) or 4bytes(8 digit HEX). If c value is 1, I want to get 2bytes (4 digit HEX) HEX array and if c value is 0, I want to get 4bytes(8 digit HEX) HEX array from a long HEX string.
After that, I want to convert while converting 2byte or 4byte to floating number( decimal number).
I have code for 4byte to a decimal value.
Dim bytes() As Byte = {&H43, &H62, &HD3, &HE}
If BitConverter.IsLittleEndian Then
Array.Reverse(bytes)
End If
Dim myFloat As Decimal = BitConverter.ToSingle(bytes, 0)
txt4.Text = myFloat
Please provide me the code for this function.
Example:
Long Hex value - 4362D30EFFC00000FFC00000FFFFFFFF
If C is 1, split 4 digit HEX values.
4362
Then convert to decimal.
17250
Again split 4 digit HEX values.
D30E
Then convert to decimal
-11506
If c is 0, split 8 digit HEX values.
4362D30E
Then convert to decimal
226.824432
Please help with this. I don't not know much about VB.Net
I'm going to give this a shot as well, but do consider what I said on your newer question.
To read a certain amount of bytes and turn them into a number best is to use the BitConverter and its To*** methods.
This is how many bytes each numeric data type uses:
Double: 8 bytes
Int16 / UInt16 / Short / UShort: 2 bytes
Int32 / UInt32 / Integer / UInteger: 4 bytes
Int64 / UInt64 / Long / ULong: 8 bytes
Single: 4 bytes
With this in mind, all you need is to decide on a data type based on the number of bytes you want to read, and then specify an index in your array where to start reading from.
Remember that if you reverse your array you have to start reading from the end of the array instead.
Dim StartIndex As Integer = 0
Dim EndIndex As Integer = bytes.Length - 1
'How many bytes to read: 2 or 4.
Dim BytesPerStep As Integer = If(C = 1, 2, 4)
'If the system uses little endianness we need to reverse the array and loop backwards.
If BitConverter.IsLittleEndian Then
'Reverse the array.
Array.Reverse(bytes)
'Swap start and end index.
StartIndex = EndIndex
EndIndex = 0
'Negate BytesPerStep: Go backwards.
BytesPerStep = -BytesPerStep
End If
'Iterate the array <BytesPerStep> bytes at a time.
For i = StartIndex To EndIndex Step BytesPerStep
If C = 1 Then
'Read two bytes = Short (Int16).
ListBox1.Items.Add(BitConverter.ToInt16(bytes, i))
Else
'Read four bytes = Single (Float)
ListBox1.Items.Add(BitConverter.ToSingle(bytes, i))
End If
Next
Examples:
Double-Number is 56.6789 result should be 4
Double-Number is 12345.67 result should be 2
Double-Number is 12345.6 result should be 1
I have a solution tinkering with strings, but I think there is an mathematical solution?
Please in VB.NET ...
Split the original number and get the length of the upper index (1)
myNumber = 12.3456
Dim count As Integer = Len(Split(CStr(myNumber), Application.DecimalSeparator)(1))
Debug.Print count // prints '4'
edit: replaced "." with decimal separator to ensure use across varying cultures
You can try like this:
Dim x As String = CStr(56.6789)
Dim count = x.Length - InStr(x, ".")
One way to do it is to keep knocking off the whole part, multiplying by 10, repeat until you have an integer:
Dim x As Double = 1.23456
Dim count As Integer = 0
While Math.Floor(x) <> x
x = (x - Math.Floor(x)) * 10D
count = count + 1
End While
Note this will fail if there is an infinite number of decimal places - so you could set a limit on it (If count > 100 Then Exit While)
Another way would be like this, which converts to a string but removes the need to hardcode the separator.
Dim x As Double = 1.23456
Dim x0 As Double = x - Math.Floor(x)
Dim x0String As String = x0.ToString()
Dim count As Integer = x0String.Substring(2, x0String.Length - 2).Length
Using Application.DecimalSeparator also allows a string to be used.
The method with a string will again lose information about an infinite-length fractional part, as it will truncate it.
I use vba in ms access,and found that ,if my parameter greater than 0x8000
less than 0x10000, the result is minus number
eg. Val("&H8000") = -32768 Val("&HFFFF")= -1
how can i get the unsigned number?
thanks!
There's a problem right here:
?TypeName(&HFFFF)
Integer
The Integer type is 16-bit, and 65,535 overflows it. This is probably overkill, but it was fun to write:
Function ConvertHex(ByVal value As String) As Double
If Left(value, 2) = "&H" Then
value = Right(value, Len(value) - 2)
End If
Dim result As Double
Dim i As Integer, j As Integer
For i = Len(value) To 1 Step -1
Dim digit As String
digit = Mid$(value, i, 1)
result = result + (16 ^ j) * Val("&H" & digit)
j = j + 1
Next
ConvertHex = result
End Function
This function iterates each digit starting from the right, computing its value and adding it to the result as it moves to the leftmost digit.
?ConvertHex("&H10")
16
?ConvertHex("&HFF")
255
?ConvertHex("&HFFFF")
65535
?ConvertHex("&HFFFFFFFFFFFFF")
281474976710655
UPDATE
As I suspected, there's a much better way to do this. Credits to #Jonbot for this one:
Function ConvertHex(ByVal value As String) As Currency
Dim result As Currency
result = CCur(value)
If result < 0 Then
'Add two times Int32.MaxValue and another 2 for the overflow
'Because the hex value is apparently parsed as a signed Int64/Int32
result = result + &H7FFFFFFF + &H7FFFFFFF + 2
End If
ConvertHex = result
End Function
Append an ampersand to the hex literal to force conversion to a 32bit integer:
Val("&HFFFF" & "&") == 65535
Val("&H8000&") == +32768
Don't use Val. Use one of the built-in conversion functions instead:
?CCur("&HFFFF")
65535
?CDbl("&HFFFF")
65535
Prefer Currency over Double in this case, to avoid floating-point issues.