How do I mirror the bits of an integer of unknown length in VB.Net?
By mirroring I mean putting the first bit last and so on.
i.E.:
10010100 mirrors to
00101001
The functions construct would be:
Public Function ReveseIntegerBitwise(ByVal initialInteger As Integer)
Dim reversedInteger As Integer
' Do Something with initialInteger and put it in reversedInteger
Return reversedInteger
End Function
You can do:
Function Foo (value as Integer) as String
Return new String(Array.Reverse(Convert.ToString(value,2).ToCharArray()))
End Function
and it returns a string with the reversed bits.
Related
I'm using vb.net. I am doing some checking and scrubbing of my data when i get it from the database. I'm using an overload but it doesn't seem to be working for decimal numbers. Decimal numbers get treated as integers.
Public Class CheckData
Public Shared Function Check(row As DataRow, columnName As String, pDefaultValue As Decimal) As Decimal
Dim x As Object = ReplaceDBNullAndColumnExists(row, columnName)
Dim y As Decimal = CDec(Dempsey.fnIsNull.IsNull(x, pDefaultValue))
Return y
End Function
Public Shared Function Check(row As DataRow, columnName As String, pDefaultValue As DateTime) As DateTime
Dim x As Object = ReplaceDBNullAndColumnExists(row, columnName)
Dim y As DateTime = Dempsey.fnIsNull.IsNull(x, pDefaultValue)
Return y
End Function
Public Shared Function Check(row As DataRow, columnName As String, pDefaultValue As Integer) As Integer
Dim x As Object = ReplaceDBNullAndColumnExists(row, columnName)
Dim y As Integer = Dempsey.fnIsNull.IsNull(x, pDefaultValue)
Return y
End Function
Public Shared Function Check(row As DataRow, columnName As String, pDefaultValue As String) As String
Dim x As Object = ReplaceDBNullAndColumnExists(row, columnName)
Dim y As String = Dempsey.fnIsNull.IsNull(x, pDefaultValue)
Return y
End Function
Public Shared Function Check(row As DataRow, columnName As String, pDefaultValue As Boolean) As Boolean
Dim x As Object = ReplaceDBNullAndColumnExists(row, columnName)
Dim y As Boolean = Dempsey.fnIsNull.IsNull(x, pDefaultValue)
Return y
End Function
So if i pass in some data and the type is a string, integer, boolean or datetime it goes to the propert function. if i pass in a decimal it goes to integer. If i set a breakpoint on the public shared function check that is a integer function and do a
row.Table.Columns(columnName).DataType.Name
I get back - "Decimal" (doing this in the immediate window)
So my question is what have i done wrong that it doesn't take it to the decimal overload and return a decimal value. By the way, the actual data value is 37.50.
Thanks
shannon
I use this to populate list.
Public Function populate(mDs As DataSet) As List(Of SR_SalaryRange_Current)
Dim rows As DataRowCollection
Dim drow As DataRow
Dim oSR_SalaryRange_Current As SR_SalaryRange_Current
Dim oSR_SalaryRange_Currents As List(Of SR_SalaryRange_Current) = New List(Of SR_SalaryRange_Current)
Dim dt As New DataTable
Try
dt = mDs.Tables("SR_SalaryRange_Currents")
rows = dt.Rows
For Each drow In rows
oSR_SalaryRange_Current = New SR_SalaryRange_Current
With oSR_SalaryRange_Current
.tblSR_SalaryRange_CurrentID = SitePlumbing.CheckData.Check(drow, "intTblSR_SalaryRange_CurrentID", 0)
.EffectiveDate = SitePlumbing.CheckData.Check(drow, "dtmEffectiveDate", CDate("1/1/1900"))
.WorkWeekHours = SitePlumbing.CheckData.Check(drow, "decWorkWeekHours", 0)
End With
oSR_SalaryRange_Currents.Add(oSR_SalaryRange_Current)
Next
Catch ex As Exception
ErrorMsg = "Populate Error:" & ex.InnerException.ToString
Return oSR_SalaryRange_Currents
End Try
Return oSR_SalaryRange_Currents
End Function
from there it goes into the checkdata that i mentioned before. In the code above it correctly goes to an integer and a datetime when hitting the overload, just isn't doing it for the decimal.
A decimal is implicitly covertable into an integer so the compiler is confused if you have OPTION STRICT set to off. You have two options:
1) Set OPTION STRICT to ON. Then the compiler will not convert implicitly.
2) Pass in a decimal literal like this: 10D (i.e. there is a D on the end telling the compiler it is a decimal).
For example:
'Sub Routine 1
public sub Test(ByVal d as decimal)
end sub
'Sub Routine 2
public sub Test(ByVal i as integer)
end sub
//Client
dim d1 as decimal={Number}D 'where {number} is replaced with a number
dim d2 as decimal={Number} 'where {number} is replaced with a number
Test(d1) 'this will always go to Sub Routine 1 regardless of whether OPTION strict is ON or OFF
Test(d2) 'this will go to Sub Routine 1 if option strict is ON. If it is OFF, then it may go to Sub Routine 2 depending on the size of the number.
I was given a way to work with this by Viorel on another forum. He suggested I do
Check(drow, "decWorkWeekHours", 0#)
and that did indeed work. When i asked what it does, this was his response.
With ‘#’, the constant ‘0#’ becomes a decimal one. Then VB.NET chooses the definition of Check that takes a Decimal parameter, since it is more suitable comparing with other candidates.
You can also write ‘0d’ [https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/type-characters].
hope that will help someone else down the road.
Thanks
shannon
I do not understand at all how to use TryCast in my code, but it is something I need to use for validating user input. I have done various searches and looked at various questions on here, but no one seems to actually say how to use it, and the MSDN website doesn't seem to help at all.
Function ValidateInput(Var_In As String) As Integer
If TryCast(Var_In, Integer) = Nothing Then
Return vbNull
Else
Return Var_In
End If
End Function
The error says that
The operand must be of reference type but Integer is of value type
What is the explanation of what I have done wrong?
TryParse doesn't accept more than 10 digits so for example, an input of "12345678901" won't be accepted. How do I fix this?
Let's try to understand the differences between TryCast, Convert and TryParse.
TryCast
This function will attempt to convert one object into another type, as long as it is a reference type.
Dim MyNewObject = TryCast(MyObject, MyReferenceClass)
If IsNothing(MyNewObject) Then
MessageBox.Show("Impossible to cast")
End If
Since Integer is a value type, it will not work, so we have to figure something out...
Convert
Convert Class on MSDN
From MSDN:
Converts a base data type to another base data type.
So we can try:
Dim myInt = Convert.ToInt32(MyObject)
The problem is that it will generate an exception InvalidCastException if it's impossible to do the conversion.
TryParse
This function is trying to convert a String into something you want. And it will not generate an exception:
Dim myInt As Integer = 0
If Not Integer.TryParse(MyString, myInt) Then
MessageBox.show("This is not an integer")
End If
Limitation
Converting a String into a Integer can sometimes be tricky... If the String represents a number that is greater or lesser than Integer.MaxValue and Integer.MinValue, you will end up with no conversion...
So you can go with a Double:
Double.TryParse(MyString, MyDouble)
Or personally, if you know that it will be a number, use Decimal:
Decimal.TryParse(MyString, MyDecimal)
See Decimals on MSDN
Decimal still has a Max and Min value, according to MSDN:
The Decimal value type represents decimal numbers ranging from positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335. The Decimal value type is appropriate for financial calculations that require large numbers of significant integral and fractional digits and no round-off errors.
Convert.ChangeType
This one is also interesting, but is a bit weird...
You are attempting to perform TryCast against an Integer, which is a value type. TryCast works only on reference types, such as (but not limited to) a Class, Object, or String type.
If you are trying to convert the input parameter to an Integer, you might try one of the methods in the Convert class, such as Convert.ToInt32() or Integer.TryParse.
Instead of TryCast, use TryParse:
Function ValidateInput(Var_In As String) As Integer
Dim iNum As Integer
If (Integer.TryParse(Var_In, iNum)) Then
Return iNum
Else
Return vbNull
End If
End Function
Much better is to use TryParse:
Function ValidateInput(Var_In As String) As Integer
Dim num as Integer
If Not Integer.TryParse(Var_In, num) Then
Return vbNull
Else
Return num
End If
End Function
I'm late to the discussion, but if anyone lands here (like I did) looking for a quick & dirty solution, here a function I'm using for simple cell validation in a DataGridView control.
Function TryTypeFit(theString As String, theType As Type, ShowError As Boolean) As Boolean
Dim TempReturn As Boolean = False
Dim TempObject As Object
Try
TempObject = Convert.ChangeType(theString, theType)
TempReturn = True
Catch ex As Exception
' didn't work
TempReturn = False
If ShowError Then
Dim eMessage As String = "Error: Value must be castable to a " & CStr(theType.Name)
MsgBox(eMessage)
End If
End Try
100:
Return TempReturn
End Function
I have looked on the web and I cannot find anything that helps me, all I can find is changing the characters into ASCII or Hexadecimal. However I would like to do it a different way. For example, say the string that got passed in was abcdef, I would like to have a key which changes these characters into another string such as qwpolz. Is there an easier way than declaring each character in the alphabet to be another character like:
Dim sText As String = "Hello"
Dim sEncode As String = ""
Dim iLength As Integer
Dim i As Integer
iLength = Len(sText)
For i = 1 To iLength
sEncode = sEncode ????
Next
Return sEncode
And then have a very lengthy loop which checks for these loops? There must be a much simpler way. Can anybody help by pointing me in the right direction?
Edit: Why downvote? Seriously, it's a legitimate question. Instead of downvoting for no reason, just move onto another question.
Well actually, this sounds like a Caesar sipher
Private Overloads Shared Function Encrypt(ByVal ch As Char, ByVal code As Integer) As Char
If Not Char.IsLetter(ch) Then
Return ch
End If
Dim offset As Char = IIf(Char.IsUpper(ch), "A", "a")
Return CType((((ch + (code - offset)) Mod 26) + offset),Char)
End Function
Private Overloads Shared Function Encrypt(ByVal input As String, ByVal code As Integer) As String
Return New String(input.ToCharArray.Select(() => { }, Encrypt(ch, code)).ToArray)
End Function
Private Shared Function Decrypt(ByVal input As String, ByVal code As Integer) As String
Return Encrypt(input, (26 - code))
End Function
Note that this assumes, that you use English alphabet. In general case where for example you have 'ä', 'ö', 'š', 'ž', 'ß', 'õ', 'ü' etc. this would not work. In that case it is simpler to just create a list/dictionary of your ordered alphabet and use it.
Example use:
encrypted = Encrypt(sText, 5)
decypted = Decrypt(encrypted, 5)
Sounds as if you want to modify a string by replacing each character with a different character according to a mapping table. An efficient approach is to use a Dictionary(Of Char, Char). But easier to write and maintain is something like this:
Shared ReadOnly replaceChars As String = "abcdef"
Shared ReadOnly withChars As String = "qwpolz"
Public Shared Function ReplaceAll(input As String) As String
Dim newChars = From c In input
Let index = replaceChars.IndexOf(c)
Select If(index >= 0, withChars(index), c)
Return String.Concat(newChars)
End Function
So the first string contains the chars that you want to replace and the second the replacement characters. Both strings must have the same length.
If you want to support case insensitivity:
Public Shared Function ReplaceAll(input As String, comparison As StringComparison) As String
Dim newChars = From c In input
Let index = replaceChars.IndexOf(c.ToString(), comparison)
Select If(index >= 0, withChars(index), c)
Return String.Concat(newChars)
End Function
Note that this is also a loop. There is no way to avoid some kind of loops if you want to replace multiple characters or strings.
So I was coding a string search function and ended up with 4 since they needed to go forwards or backwards or be inclusive or exclusive. Then I needed even more functionality like ignoring certain specific things and blah blah.. I figured it would be easier to make a slightly bigger function with optional boolean parameters than to maintain the 8+ functions that would otherwise be required.
Since this is the main workhorse function though, performance is important so I devised a simple test to get a sense of how much I would lose from doing this. The code is as follows:
main window:
Private Sub testbutton_Click(sender As Object, e As RoutedEventArgs) Handles testbutton.Click
Dim rand As New Random
Dim ret As Integer
Dim count As Integer = 100000000
Dim t As Integer = Environment.TickCount
For i = 0 To count
ret = superfunction(rand.Next, False)
Next
t = Environment.TickCount - t
Dim t2 As Integer = Environment.TickCount
For i = 0 To count
ret = simplefunctionNeg(rand.Next)
Next
t2 = Environment.TickCount - t2
MsgBox(t & " " & t2)
End Sub
The functions:
Public Module testoptionality
Public Function superfunction(a As Integer, Optional b As Boolean = False) As Integer
If b Then
Return a
Else
Return -a
End If
End Function
Public Function simpleFunctionPos(a As Integer)
Return a
End Function
Public Function simplefunctionNeg(a As Integer)
Return -a
End Function
End Module
So pretty much as simple as it gets. The weird part is that the superfunction is consistently twice faster than either of the simple functions (my test results are "1076 2122"). This makes no sense.. I tried looking for what i might have done wrong but I cant see it. Can anybody explain this?
You didn't set a return type for simple function. So they return Object type.
So when you using simpleFunctionNeg function application convert Integer to Object type when returning value, and then back from Object to Integer when assigning returning value to your variable
After setting return value to Integer simpleFunctionNeg was little bid faster then superfunction
Please see the code below:
Public Function Test()
Dim o As Object = getVariable("Integer")
If TypeOf o Is Integer Then
'Do some processing on the integer
ElseIf TypeOf o Is Decimal Then
'Do some processing on the integer
End If
End Function
Public Function getVariable(ByVal strDataType As String)
If strDataType = "Integer" Then
Return New Integer
ElseIf strDataType = "Decimal" Then
Return New Decimal
ElseIf strDataType = "Double" Then
Return New Double
End If
End Function
I suspect there is an easier way (fewer lines of code) of doing this with Reflection?
You can use Type.GetType together with Activator.CreateInstance:
Public Function getVariable(ByVal strDataType As String)
Return Activator.CreateInstance(Type.GetType(strDataType))
End Function
For strDataType you need to be using System.Int32, System.Decimal and System.Double respectively. If you want to keep it as Integer etc., you need to incorporate string translation, for example, have a Dictionary(Of String, String), with entries like ("Integer", "System.Int32").
The real question is what ars you trying to solve? Activator will work. Are trying to create a factory or an IOC container. Could you provide more detail? You could also create a dictionary were the key is of type string and then item stores delegates used to actual create the type.