Shop OBEX P1 Docs P2 Docs Learn Events
Ripping a single bit out of a Long — Parallax Forums

Ripping a single bit out of a Long

SarielSariel Posts: 182
edited 2012-07-05 13:18 in Propeller 1
I am trying to take just the MSB of a long (one bit of info), and depending on if it is a 1 or a 0 do some other program trickery with if/else statements. Is there an easy way of doing this? I initially tried this:
  NetTemp := L[BasePin]   
  repeat 32
      if NetTemp => 00_0000_0000_0000_0000_0000_0000_0000  
        .....
      else
        ...
    NetTemp <-= 1


(L[BasePin] is a 128 long buffer that is loaded from an SD card earlier in the program, just to get that clarified.)

but that really gets confusing since that is actually a negative number when converted to decimal, so there is no way to base a greater than/less than off of this method when taking into consideration that the rest of the bits in the var "NetTemp" could be anything, making it a positive or negative number. I also tried:

NetTemp := ||L[BasePin]   
if NetTemp => 00_0000_0000_0000_0000_0000_0000_0000
  .....


and I was still getting odd results. anyone know of some way of isolating just the MSB, even if it is to another variable so that I can do some true/false work?

Comments

  • lonesocklonesock Posts: 917
    edited 2012-07-02 10:33
    Spin uses signed integers, and a nifty thing to note is all negative numbers have the MSB set, so...

    if x < 0

    Jonathan
  • SarielSariel Posts: 182
    edited 2012-07-02 10:37
    Just noticed a silly type-o in my code above... it should have read..
    if NetTemp => %1000_0000_0000_0000_0000_0000_0000_0000
    

    I assume that does not matter, and lonesock is still correct?
  • SarielSariel Posts: 182
    edited 2012-07-02 10:43
    AHHHA! I see what you mean. MSB designates the + or - status of the number then.. very clever indeed. thanks a bunch buddy. program is acting normal now.
  • JonnyMacJonnyMac Posts: 9,194
    edited 2012-07-02 11:02
    I have this method in my standard template:
    get_bit(value, pos)
    
      return (value >> pos) & 1
    
  • SarielSariel Posts: 182
    edited 2012-07-02 11:11
    Yet another reason to love you folks. Find a few ways to skin a cat, and learn something every time I am here. Thanks for the snip Jon. I'm sure I will be using that one.
  • HShankoHShanko Posts: 402
    edited 2012-07-02 11:30
    Sounds cruel to RIP a bit out of a long. Then you have a 31 bit 'almost' long. They gave you good advice; just test the bit. None of that mean ripping.
  • Vega256Vega256 Posts: 197
    edited 2012-07-02 16:56
    HShanko wrote: »
    Sounds cruel to RIP a bit out of a long. Then you have a 31 bit 'almost' long. They gave you good advice; just test the bit. None of that mean ripping.
    I suppose, though, that you can never destroy a piece of digital information; the long lives forever.
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-07-02 18:21
    You could kind of sneak up and peak at the bit and then leave it there.

    Duane J
  • nohabnohab Posts: 96
    edited 2012-07-03 02:25
    Jon, do you by any chance also have such a handy "set_bit" method?
  • BitsBits Posts: 414
    edited 2012-07-03 10:27
    nohab wrote: »
    Jon, do you by any chance also have such a handy "set_bit" method?


    I do
    Pub Bits (In,bit,value)
         Result  := (In & !(1 << bit)) | (value << bit)
    

    Where...

    value = 1 or 0
    in = the original number
    bit = what bit in the long.
  • photomankcphotomankc Posts: 943
    edited 2012-07-03 10:38
    Nice. Took me a sec to get the (In & !(1<<bit)) thing but I get it. I need to add that to the parts bin.
  • nohabnohab Posts: 96
    edited 2012-07-04 07:14
    Bits wrote: »
    I do

    Thanks !
    Clever code :-)
  • JonnyMacJonnyMac Posts: 9,194
    edited 2012-07-04 10:38
    nohab wrote: »
    Jon, do you by any chance also have such a handy "set_bit" method?


    This is my version from a user-friendly programming template for the EFX-TEK HC-8+
    pub set_bit(target, pos, newbit)
    
      if ((pos => 0) and (pos =< 31))                               ' if good bit position
        if (newbit)                                                 '  if true/1
          target |= (1 << pos)                                      '   set the bit                                     
        else                                                        '  if false/0
          target &= !(1 << pos)                                     '   clear the bit
    
      return target
    


    My version is a little less clever than the neat one-liner that Bits showed you; again, mine is built into a programming template that is intended to be easy on Spin newbies. Mine will also set the bit for any non-zero value in the newbit parameter. This allows me to use true and false results from other operations, for example, as in this program I was working on yesterday that looks for specific numbered files on an SD card
    repeat idx from 0 to 15
        make_filename(idx)
        inventory := set_bit(inventory, idx, open_file(@FileName, "r")) 
        close_file
    
  • nohabnohab Posts: 96
    edited 2012-07-05 13:18
    Thanks Jon,

    Your solution is pretty close to my first thoughts, it's very easily understood and has indeed an advantage with non-zero-or-one values.
    Bits solution seems efficient (faster ?), so I guess it's still true that there are pros and cons with every design.

    /Nick
Sign In or Register to comment.