Shop OBEX P1 Docs P2 Docs Learn Events
Specific bit — Parallax Forums

Specific bit

bpislifebpislife Posts: 10
edited 2010-08-05 23:20 in Propeller 1
Is there anyway to check to see if a particular bit is a "1" using SPIN?

In other words, I have a byte of data and want to check to see if the 3rd bit is a "1".

x = don't care

xxxxx1xx

I know how I would do this on a PC the old fashion way by using the VB left and VB right command until I have trimmed off all the bits I don't need but I am not sure how to do this with SPIN.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2010-08-04 02:34
    You simply start by creating a mask of bits you're interested in, then AND it with your variable. For example

    data := byte[noparse][[/noparse] 5]                  ' pick a random byte (this is the CRC for your program)
    mask := |< 2                      ' create mask (3rd bit is bit 2)
    if data & mask                    ' AND data with mask, non-zero gets propagated to TRUE
      print(string("bit 3 is set"))   ' fake print method to illustrate action taken
    
  • bpislifebpislife Posts: 10
    edited 2010-08-04 02:49
    Thanks Kuroneko. Can you explain the if statement a bit more. I don't fully understand what ANDing the data and the mask. I guess my question is with MASK. I already read the user guide and it just isn't sinking in.

    Thanks!!
  • Mike GreenMike Green Posts: 23,101
    edited 2010-08-04 03:02
    mask in this case is the value %0100. When you do a logical AND (&) of data with mask, you get a zero if the 3rd bit of data is zero. You get a non-zero (%0100) value if the 3rd bit of data is a one. The IF statement tests for a non-zero value and succeeds if that's true.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-08-04 03:41
    I use the following routines in many of my programs:

    pub getbit(target, pos)
    
    '' returns target.pos
    
      return (target & (1 << pos)) >> pos
    
    
    pub putbit(target, pos, value)
    
    '' writes value.0 to target.pos
    
      if (value & 1)
        target |= (1 << pos)
      else
        target &= !(1 << pos)
    
      return target
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • bill190bill190 Posts: 769
    edited 2010-08-04 04:32
    This has to do with "logic gates" or "AND gates" which are basic parts of computers.

    Here is a link to a diagram of an AND gate...

    http://www.ee.surrey.ac.uk/Projects/Labview/gatesfunc/GateMain.htm

    ...on the left are two inputs. On the right one output...

    If your inputs are 1 and 0 (one and zero), the output will be 0 (zero).

    Or 0 and 1 = 0 as well.

    But if the inputs are 1 and 1, then the output would be 1.

    So just using that·AND gate and·a single digit Mystery number, we could·AND that single digit number with another number. Or with what is called a·Mask. A mask is·just a number or a string or numbers.

    So let's set the mask to 1, then AND it with the Mystery number...

    ANSWER: The output is a 1!

    What is our Mystery number? It is a 1.

    You can AND the upper row with the bottom row...

    10101011

    00000001 (mask)

    output = 1

    The mask does not allow any numbers to be a 1 except the last digit because they are all 0's except the last digit...
  • bpislifebpislife Posts: 10
    edited 2010-08-04 19:09
    Thanks Mike, that was the kind of explanation I was looking for. I know all about logic gates and such so my question was more what the mask was actually doing.

    That makes perfect sense now.

    Thanks everyone for you inputs.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2010-08-05 04:30
    JohnnyMac - It'd be more efficient to do this for the GetBit routine:


    pub getbit(target, pos)
    return (target >> pos) & 1

    As that's only doing a single shift, plus the AND of a constant.

    To explain further, it shifts the bit position you're interested in down to the 1st bit, then ANDs off all bits but the lowest one.

    Jason
  • bpislifebpislife Posts: 10
    edited 2010-08-05 11:04
    Interesting. So using my example, is this correct?

    data := %11111111   'byte of data
    getbit(data, 3)
    return (data>> 3) & 1
    
    



    This doesn't look right.
  • bill190bill190 Posts: 769
    edited 2010-08-05 17:42
    I think that was intended to be a separate method/function/object (the pub part).

    Like on page 70 of the Propeller Education Kit Labs pdf...

    ·


  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-08-05 21:37
    bpislife,

    Jason was posting an alteration to Jonny's methods (you could use those methods in your code if you wanted)

    You could use Jonny's get bit routine like this:

    if  getbit(data, 3)         
       run this code            ' runs this code if bit 3 is set
    
    



    or not using the method:

    if  (data >> 3) & 1       ' Shifts bit of interest to bit0 and ANDs it with 1.
       run this code            ' runs this code if bit 3 is set
    
    



    Graham
  • bpislifebpislife Posts: 10
    edited 2010-08-05 21:43
    You guys have been an awesome! Thanks!!
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-08-05 23:20
    Good point, Jahson. I am, sometimes, overly-verbose with my code when I first write it and get too busy to go back and refine. Your suggestion makes perfect sense.

    JasonDorie said...
    JohnnyMac - It'd be more efficient to do this for the GetBit routine:


    pub getbit(target, pos)
    return (target >> pos) & 1

    As that's only doing a single shift, plus the AND of a constant.

    To explain further, it shifts the bit position you're interested in down to the 1st bit, then ANDs off all bits but the lowest one.

    Jason
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
Sign In or Register to comment.