charlieb01
asked on
VB. Net Need help decoding a number 2 to the nth power
Hello,
I have an application where a piece of hardware is going to give my VB.Net program a number to tell me which valves are open. Each valve has a value associated based on 2 to the nth power. So:
Valve01 = 1
Valve02 = 2
Valve03 = 4
Valve04 = 8
Valve05 = 16
etc. (up to 20 Valves)
So, if valves 1, 4 and 5 are open, the number I will get will be 1 + 8 + 16 = 25
I am looking for some help in decoding this so I know which valves are open. For five valves, it is not too difficult as the largest number is 31 but the code would get lengthy when I am looking at 20 valves as the value for the 20th valve alone is 2^19 = 524288.
Dose anyone have a simple way to decode this in VB.net?
Thanks,
Charlie
I have an application where a piece of hardware is going to give my VB.Net program a number to tell me which valves are open. Each valve has a value associated based on 2 to the nth power. So:
Valve01 = 1
Valve02 = 2
Valve03 = 4
Valve04 = 8
Valve05 = 16
etc. (up to 20 Valves)
So, if valves 1, 4 and 5 are open, the number I will get will be 1 + 8 + 16 = 25
I am looking for some help in decoding this so I know which valves are open. For five valves, it is not too difficult as the largest number is 31 but the code would get lengthy when I am looking at 20 valves as the value for the 20th valve alone is 2^19 = 524288.
Dose anyone have a simple way to decode this in VB.net?
Thanks,
Charlie
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hi charlieb01;
Here is VB code that uses Enums which will give you the valves selected from an integer value.
Here is VB code that uses Enums which will give you the valves selected from an integer value.
' Place this at class level outside of any function or subroutine.
<Flags> Private Enum valvesEnum As Integer
valve01 = 1
valve02 = 2
valve03 = 4
valve04 = 8
valve05 = 16
valve06 = 32
valve07 = 64
valve08 = 128
valve09 = 256
valve10 = 512
valve11 = 1024
valve12 = 2048
valve13 = 4096
valve14 = 8192
valve15 = 16394
valve16 = 32768
valve17 = 65536
valve18 = 131072
valve19 = 262144
valve20 = 524288
End Enum
' Then in a function, subroutine or event handleryou can do this.
' Test data that the hardware sends to you
Dim valvesSelected As valvesEnum = 25
' Array holds the valves which are open
Dim valves() As String = String.Format("{0:G}", valvesSelected).Split(New Char() {","c, " "c}, StringSplitOptions.RemoveEmptyEntries)
' Output valves that are open
For Each valve In valves
Console.WriteLine(valve)
Next
The right way to do this is with the binary SHIFT and AND operators
Sub Main()
Dim val As Int32
Dim i As Int32
Dim valve As Int32
val = 25 ' The value you receive
valve = 1 ' Bit mask to check for on values
' You can change this for as many valves as your system has
For i = 0 To 32
' AND the value with the current mask to see if the valve is on
' and output it if it is
If val And valve Then
Console.WriteLine("Valve " & valve & " is open")
End If
' Shift the mask 1 position left for the next match
valve = valve << 1
Next
Console.WriteLine("Done")
End Sub
Function IsValveSelected(ByVal index As Integer, ByVal value As Integer) As Boolean
Return CBool(value And 2 ^ (index - 1))
End Function
Dim x As Integer = 25
Debug.Print("Initial value: " & x)
Debug.Print("==========================")
For i = 1 To 20
Debug.Print(String.Format("valve #{0} selected: {1}", i, IsValveSelected(i, x)))
Next
the vb code prints out the list of valves like this 00000000000000000001000
left to right
meaning the fourth valve is open
You will see it in the console.
if you want to be sure, send it to a message box like this
dim i = 8
msgbox(Convert.ToString(i, 2).PadLeft(20, "0"C))
DIM i - creates a variable where you add a number, for testing, and we set it to 8, but you can set it to whatever number you need
try 262144 for valve 19
or 262145 for valve 19 and valve 1
left to right
meaning the fourth valve is open
You will see it in the console.
if you want to be sure, send it to a message box like this
dim i = 8
msgbox(Convert.ToString(i,
DIM i - creates a variable where you add a number, for testing, and we set it to 8, but you can set it to whatever number you need
try 262144 for valve 19
or 262145 for valve 19 and valve 1
There should be no need to make use of strings or split functions for this. This type of system has been around for years and is ideally suited to using BITWISE operators to determine what flags are set.
A typical input might be 00010001011101
Indicating that valves 1,3,4,5,7,11 are open
To decode this is a simple exercise using a mask. A mask is a value applied to another value using a bitwise operation (AND / OR / XOR ) to give a new value.
AND is the intersection
OR is the union
XOR is the complement
So to find the valve values start with a mask value of 1.
Loop through the maximum number of flags supported (example 32) and each iteration AND the mask with the value and then shift the mask left 1 position (effectively multiply by 2)
So:
SHIFT and AND
A typical input might be 00010001011101
Indicating that valves 1,3,4,5,7,11 are open
To decode this is a simple exercise using a mask. A mask is a value applied to another value using a bitwise operation (AND / OR / XOR ) to give a new value.
AND is the intersection
OR is the union
XOR is the complement
So to find the valve values start with a mask value of 1.
Loop through the maximum number of flags supported (example 32) and each iteration AND the mask with the value and then shift the mask left 1 position (effectively multiply by 2)
So:
mask starts: 1 or (00000000000001)
AND with Value00010001011101
00000000000001 AND
00000000000001 Result is > 0 therefore valve 1 is set
Now shift the mask 1 bit to the leftmask = mask << 1
AND again00010001011101
00000000000010 AND
00000000000000 Result is 0 - therefore valve 2 is NOT set
SHIFT and AND
00010001011101
00000000000100 AND
00000000000100 Result is > 0 therefore valve 3 is set
This above is the simplest and most efficient way of solving this problem. Refer here for source
sorry, forgot to mention, but it should of been picked up, the VB i wrote prints to the console.
I gave the code for a mesagebox, or you can do whatever with it, like send it to a variable
I gave the code for a mesagebox, or you can do whatever with it, like send it to a variable
ASKER
The VB sample does not seem to do anything.
Can you assist in converting your C# into VB?
Thanks