Results 1 to 17 of 17

Thread: power of 2 and binary numbers...

  1. #1

    Thread Starter
    Hyperactive Member brenaaro's Avatar
    Join Date
    Sep 2001
    Location
    Montreal, Canada
    Posts
    391

    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:
    1. const flag1 = 2 '0000 0010
    2. const flag2 = 8 '0000 1000
    3. Dim L As Long
    4. Dim I As Integer
    5.    
    6. L = flag1 Or flag2 ' L is 0000 1010
    7.  
    8. If (L And flag1) = flag1 Then
    9.    
    10.     I = ' code to find which bit in flag1 is turned on (should return 2)
    11.    
    12.     Msgbox "The " & i & "nd bit is on"
    13.    
    14. End If
    15.  
    16. If (L And flag2) = flag2 Then
    17.    
    18.     I = ' code to find which bit in flag2 is turned on (should return 4)
    19.    
    20.     Msgbox "The " & i & "th bit is on"
    21.    
    22. 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.

  2. #2
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    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:
    1. i = 0
    2.     k = flag
    3.     Do While k > 1
    4.         k = k \ 2 'Notice: \ means integer division
    5.         i = i + 1
    6.     Loop
    7.     'So that i is the result you want
    8.     'Btw, the rightmost bit is number 0

  3. #3
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    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:
    1. const flag1 = 2 '0000 0010
    2. const flag2 = 8 '0000 1000
    3. Dim L As Long
    4. Dim I As Integer
    5.    
    6. L = flag1 Or flag2 ' L is 0000 1010
    7.  
    8. If (L And flag1) = flag1 Then
    9.  
    10.   'Flag1 is set - so run appropriate code
    11.    
    12. Else
    13.  
    14.   'Flag1 is NOT set - so run appropriate code
    15.  
    16. End If
    17.  
    18. If (L And flag2) = flag2 Then
    19.  
    20.   'Flag2 is set - so run appropriate code
    21.  
    22. Else
    23.  
    24.   'Flag2 is NOT set - so run appropriate code
    25.    
    26. End If

  4. #4
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863
    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:
    1. Private Sub Make_Flags(Flagmemory as Long)
    2. Dim flags() As Boolean
    3. Dim i As Integer
    4. Dim Test As Long
    5. Dim Erg As String
    6. Test = 2
    7. i = 0
    8. Do
    9.     Test = 2 ^ i
    10.     If Test > CLng(Flagmemory) Then Exit Do
    11.     i = i + 1
    12. Loop
    13. i = i - 1
    14. ReDim flags(i)
    15. Do Until i = -1
    16.    
    17.     If Flagmemory - 2 ^ i >= 0 Then
    18.         flags(i) = True
    19.         Flagmemory = Flagmemory - 2 ^ i
    20.     End If
    21.     Erg = Erg + CStr(flags(i))
    22.     i = i - 1
    23. Loop
    24. 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!

  5. #5

    Thread Starter
    Hyperactive Member brenaaro's Avatar
    Join Date
    Sep 2001
    Location
    Montreal, Canada
    Posts
    391
    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:
    1. asDesc(0) = "This is flag1!"
    2. asDesc(1) = "This is flag2!"
    3. asDesc(2) = "This is flag3!"
    4. asDesc(3) = "This is flag4!"
    5.  
    6. const flag1 = 1 ' 0th bit
    7. const flag2 = 2 ' 1st bit
    8. const flag3 = 4 ' 2nd bit
    9. const flag4 = 8 ' 3rd bit
    10.  
    11. Dim L As Integer
    12. Dim S As String
    13.  
    14. L = flag3
    15.  
    16. S = asDesc(Log(L) / Log(2))
    17.  
    18. ' OR?
    19.  
    20. 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:
    1. Dim I As Integer
    2. Dim J As Integer
    3. Dim K As Integer
    4.  
    5. I = 3
    6.  
    7. J = 2 ^ I ' 2 raised to the power 3. J is now 8
    8.  
    9. K = ' some calculation on J, which should return 3
    10.  
    11. If K = I Then
    12.   MsgBox "it worked!"
    13. 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.

  6. #6

  7. #7
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863
    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!

  8. #8
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397
    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.


  9. #9
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863
    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!

  10. #10
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397
    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

  11. #11
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863
    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!

  12. #12
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573
    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!

  13. #13
    Addicted Member
    Join Date
    Feb 2001
    Posts
    198
    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

  14. #14

  15. #15
    pathfinder NotLKH's Avatar
    Join Date
    Apr 2001
    Posts
    2,397
    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:
    1. If (flags AND 1) = 1, then
    2.       MyOut = MyOut & Message(0)
    3. Endif
    4. If (flags AND 2) = 2, then
    5.       MyOut = MyOut & Message(1)
    6. Endif
    7. If (flags AND 4) = 4, then
    8.       MyOut = MyOut & Message(2)
    9. Endif
    10. 'And so on...

    Which, any normal coder would set into a loop. :;
    But he doesn't want to loop.

    -Lou

  16. #16
    Addicted Member
    Join Date
    Feb 2001
    Posts
    198
    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 )

  17. #17

    Thread Starter
    Hyperactive Member brenaaro's Avatar
    Join Date
    Sep 2001
    Location
    Montreal, Canada
    Posts
    391
    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
  •  



Click Here to Expand Forum to Full Width