|
-
Jul 14th, 2003, 08:23 AM
#1
Thread Starter
Hyperactive Member
power of 2 and binary numbers...
In VB, I'm going to have a set of flag constants that are powers of 2 (1,2,4,8,16,32,64, etc) so that my flag variable (a long integer) can have many combinations of those flags (using 'Or' to build the value and 'And' to read it)
Anyways, how can I take a number that's made up of 2 or more of these flags, and then find out which bits in the number are set to 1
Example..
VB Code:
const flag1 = 2 '0000 0010
const flag2 = 8 '0000 1000
Dim L As Long
Dim I As Integer
L = flag1 Or flag2 ' L is 0000 1010
If (L And flag1) = flag1 Then
I = ' code to find which bit in flag1 is turned on (should return 2)
Msgbox "The " & i & "nd bit is on"
End If
If (L And flag2) = flag2 Then
I = ' code to find which bit in flag2 is turned on (should return 4)
Msgbox "The " & i & "th bit is on"
End If
So basically, I need to know how to know which power of 2 a number is.
And I, for one, welcome our new insect overlords. I'd like to remind them as a trusted TV personality, I can be helpful in rounding up others to toil in their underground sugar caves.
-
Jul 15th, 2003, 02:58 AM
#2
Re: power of 2 and binary numbers...
Originally posted by brenaaro
...
...So basically, I need to know how to know which power of 2 a number is.
Strictly speaking, the fastest way to do it is by directly calculating the power:
i = log(flag) / log(2)
(the log can be any base as long as it's the same both for the numerator and the denominator)
This could however lead to nasty surprises because of roundoff so, a more reliable way to do it would be something like:
VB Code:
i = 0
k = flag
Do While k > 1
k = k \ 2 'Notice: \ means integer division
i = i + 1
Loop
'So that i is the result you want
'Btw, the rightmost bit is number 0
-
Jul 15th, 2003, 03:55 AM
#3
Re: power of 2 and binary numbers...
[QUOTE]Originally posted by brenaaro
So basically, I need to know how to know which power of 2 a number is.
Why?
The code you have is exactly what you need, you just need to put in the code to do the work.
VB Code:
const flag1 = 2 '0000 0010
const flag2 = 8 '0000 1000
Dim L As Long
Dim I As Integer
L = flag1 Or flag2 ' L is 0000 1010
If (L And flag1) = flag1 Then
'Flag1 is set - so run appropriate code
Else
'Flag1 is NOT set - so run appropriate code
End If
If (L And flag2) = flag2 Then
'Flag2 is set - so run appropriate code
Else
'Flag2 is NOT set - so run appropriate code
End If
-
Jul 15th, 2003, 05:46 AM
#4
I guess you need a way to find all flags set without having to do an If statement for each flag.
So try this code, it makes an array (flags()) which are set to true or false. flags(0) is the flag for 2^0 which is 1.
VB Code:
Private Sub Make_Flags(Flagmemory as Long)
Dim flags() As Boolean
Dim i As Integer
Dim Test As Long
Dim Erg As String
Test = 2
i = 0
Do
Test = 2 ^ i
If Test > CLng(Flagmemory) Then Exit Do
i = i + 1
Loop
i = i - 1
ReDim flags(i)
Do Until i = -1
If Flagmemory - 2 ^ i >= 0 Then
flags(i) = True
Flagmemory = Flagmemory - 2 ^ i
End If
Erg = Erg + CStr(flags(i))
i = i - 1
Loop
End Sub
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Jul 16th, 2003, 12:29 PM
#5
Thread Starter
Hyperactive Member
Thanks for the replies, I'll give a bit more detail.
It seems that ktrmrtz's answer is closest to what I need, but in what conditions would that round-off become an issue? I will only be using integer values and I was hoping to avoid any loops or other code that takes more than 1 line.
I know that using the current code I can detect wether or not a flag has been set, that is no problem. What I'm looking for is a simple (read: not a loop) way to find out which bit that flag represents (0 based is fine).
The reason for this is that I am storing a text description of what the flag represents in a string array and I want to be able to access that description directly.
Example:
VB Code:
asDesc(0) = "This is flag1!"
asDesc(1) = "This is flag2!"
asDesc(2) = "This is flag3!"
asDesc(3) = "This is flag4!"
const flag1 = 1 ' 0th bit
const flag2 = 2 ' 1st bit
const flag3 = 4 ' 2nd bit
const flag4 = 8 ' 3rd bit
Dim L As Integer
Dim S As String
L = flag3
S = asDesc(Log(L) / Log(2))
' OR?
S = asDesc(<some calculation involving L>)
S should now be "This is flag3!"
This is a pretty basic run-down but it should explain what I'm trying to accomplish.
simple example:
VB Code:
Dim I As Integer
Dim J As Integer
Dim K As Integer
I = 3
J = 2 ^ I ' 2 raised to the power 3. J is now 8
K = ' some calculation on J, which should return 3
If K = I Then
MsgBox "it worked!"
End If
And I, for one, welcome our new insect overlords. I'd like to remind them as a trusted TV personality, I can be helpful in rounding up others to toil in their underground sugar caves.
-
Jul 16th, 2003, 03:16 PM
#6
Originally posted by brenaaro
S should now be "This is flag3!"
What should S be if there is more than 1 flag set?
-
Jul 16th, 2003, 03:59 PM
#7
Good point NotLKH, the reason to use this to store the flagsetting is, to keep only one Var in memory for all flags.
so the flag-var can have any Integer-Value, and you have to determine which powers of 2 are altoghter stored in there (like 5 is 1*2^0 + 0*2^1 +1*2^2 or better 101). You want to do that without a loop?, ok than you need an If for each possible flag. The fun is all yours.
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Jul 16th, 2003, 04:09 PM
#8
Originally posted by opus
Good point NotLKH, the reason to use this to store the flagsetting is, to keep only one Var in memory for all flags.
so the flag-var can have any Integer-Value, and you have to determine which powers of 2 are altoghter stored in there (like 5 is 1*2^0 + 0*2^1 +1*2^2 or better 101). You want to do that without a loop?, ok than you need an If for each possible flag. The fun is all yours.
Good Point, opus. So, if you used more than 1 var in memory, it could be done without looping at the time you need to detect the flags.
If you are going to have a max of eight flags, thats 256 possible combinations, I'd suggest a String array dimmed to 255, then initialize each element with whatever message you want displayed, in the form load event.
You'd still have to loop, but only upon startup. Then, anytime you want your switches displayed, say bits 1, 2, and 4 were set in an Integer, lets call it MyFlag {Which in this example, MyFlag = 11} , doing a msgbox FlagMess(MyFlag ), {where FlagMess() is your string array initialized during the load event} which would have been preset to be a string saying:
"Flag 1 is set, and Flag 2 is set, and Flag 4 is set".
Generically, doing it this way, given any Int from 0 thru 255, this should work.
-
Jul 16th, 2003, 04:19 PM
#9
And doing that the point to store the flags in such a way is totally lost!
Instead of using 1 Var to store the setting of 8 flags, you use an array of 255 elements! Are you in any way connected to Memory-producers?
Last edited by opus; Jul 16th, 2003 at 04:22 PM.
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Jul 16th, 2003, 05:18 PM
#10
Originally posted by opus
Are you in any way connected to Memory-producers?
Are you talking to me?
I personally would do the looping to build the output message, but he seems to think it would slow down the program.
Of course, the time it takes to pop up a msgbox and having the user respond to it is hundreds if not thousands of times greater than the time it would take to loop thru the bits!
And, even if its not a msgbox, it sounds like its important for the user to read the message stating the status of the flags, so obviously the program isn't going to do anything until the user responds, however the message is displayed. so whats a few clock ticks to loop?
I Like Looping, heck, My Parents Liked looping, or else I'd have been named Bob!
-Lou
-
Jul 17th, 2003, 12:39 AM
#11
NotLKH, I'm sorry , I was just trying to be sarcastic.
You're welcome to rate this post!
If your problem is solved, please use the Mark thread as resolved button
Wait, I'm too old to hurry!
-
Jul 17th, 2003, 02:55 AM
#12
Originally posted by brenaaro
S = asDesc(Log(L) / Log(2))
I think this may cause problems. Even though you're using integers, both returned logs are real non-integer numbers and here's where the roundoff may throw off your scheme in some cases. For example, if you take log(4) / log(2) the result is approx. 0.60206 / 0.30103 = 2 but depending on the precision you work with this might be returned as 1.999999 or whatever, so the roundoff -if calculated as INT(result)- would return 1. It may work, though, if you calculate CI[log(4) / log(2)] where CI means "the closest integer" (offhand I can't remember whether VB has any built-in function for that), but generally speaking I would advocate to stick to integers wherever possible. Keep it simple!
-
Jul 18th, 2003, 12:13 PM
#13
Addicted Member
May be above but I didn't see it:
If (flags AND 1) = 1, then bit 0 is set
If (flags AND 2) = 2, then bit 1 is set
If (flags AND 4) = 4, then bit 2 is set
etc.
Only eight tests required
-
Jul 19th, 2003, 01:21 PM
#14
Originally posted by opus
NotLKH, I'm sorry , I was just trying to be sarcastic.
I Know! I Didn't mean to sound upset, if I did. Sorry!
-
Jul 19th, 2003, 01:26 PM
#15
Originally posted by Starman
May be above but I didn't see it:
If (flags AND 1) = 1, then bit 0 is set
If (flags AND 2) = 2, then bit 1 is set
If (flags AND 4) = 4, then bit 2 is set
etc.
Only eight tests required
True, however he wants a return of the entire status, so your code would have to be along the lines of:
VB Code:
If (flags AND 1) = 1, then
MyOut = MyOut & Message(0)
Endif
If (flags AND 2) = 2, then
MyOut = MyOut & Message(1)
Endif
If (flags AND 4) = 4, then
MyOut = MyOut & Message(2)
Endif
'And so on...
Which, any normal coder would set into a loop. :;
But he doesn't want to loop.
-Lou
-
Jul 21st, 2003, 03:06 AM
#16
Addicted Member
ah yes, sounds like the 255 string array is the answer then. Using the result of 'flag1 Or flag2' to find the index.
msg=MsgArray( flag1 Or flag2 )
-
Jul 21st, 2003, 10:37 AM
#17
Thread Starter
Hyperactive Member
Thanks for all the info guys. A lot of what you said makes sense about how having more than one flag set would create problems when trying to build a response message. Well not real "problems" per se, but no matter which way I went about it it would involve many If's or Do's.
Anyways, this question was more of a "Hmm..I wonder if such a thing is possible..." than an "Arg! I need to figure this out now!" 
Thanks again for the input!
And I, for one, welcome our new insect overlords. I'd like to remind them as a trusted TV personality, I can be helpful in rounding up others to toil in their underground sugar caves.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|