Shop OBEX P1 Docs P2 Docs Learn Events
How many 1's ? (in a given long) — Parallax Forums

How many 1's ? (in a given long)

UltraLazerUltraLazer Posts: 30
edited 2009-11-20 21:55 in Propeller 1
Hi Forum, I'm doing some brain stroming on papper before I begin to code (in spin) and am a bit stuk. I have to establish how many 1's or 0's (as I can infer on from the other) are within the first 16bits of a given long (32bit) in an array. The last 16bits (xxxx) don't matter I only care about the first word; $xxxx_????. The evaluation should be a number between 0 and 16.

There are Long, Word, and Byte, variable modifiers and none for NIB or BIT (previous parallax convention). Are NIB and BIT somehow redundant in spin?
I have seen a few examples in the using <<, >>, &, and mask to isolate data in a longer entry, but my understanding of binary operations is sill fuzzy.

Can any one spare a lesson?

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-11-20 21:39
    NIB and BIT are not provided in Spin except in the special cases of the I/O registers where you can specify any sequence of bits (like OUTA[noparse][[/noparse]5..1]). You have to use shifts and bit logical operations.

    There's no instruction in assembly that would do this for you although it's been suggested for the Prop II. In Spin, you'd do:
    PRI countBits(value) : count
    repeat 16
       count += value & 1
       value >> 1
    


    Note that count is initialized to zero when the method is called. This is for the low order 16 bits. If you want to do it on the most significant 16 bits, just add "value >> 16" before the repeat. You could also do:
    PRI countBits(value) : count
    repeat 16
       value <- 1
       count += value & 1
    

    Post Edited (Mike Green) : 11/20/2009 9:45:15 PM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-11-20 21:49
    I don't know NIB or BIT, but I guess it's for accessing nibbles and bits. These are not available in SPIN.

    You really have to count all 1s in a loop. So, what you need is a counter variable and ... the loop. Easiest thing would be to mask bit number 0. This has value 1. So, after masking you can simply add the result to your counter variable. Then you shift the value 1 bit to the right. After 16 turns you have your result. Please note: with shifting the variable you destroy the content. So, if you need it afterwards you should use a copy for counting the 1-bits.

    A possibly faster way would be to mask the least significant nibble and have a lookup-table which gives you the number of bits for all 16 possible values. Then shift to the right by 4. After 4 loops you have the result.

    How do you mask? Simply use the & operator (bitwise and). If you are interested in the content of the least significant bit of a variable, you simply use %00000000_00000000_00000000_00000001 ... or %1 in short.
    As the leading bits are all 0 you know that 'anding' any value with this will return 0 bits for those. Only the last bit is 1, so here the result depends on what that bit looks like in the value.

    >> is for shifting the bits. If you shift by 3 then the 3 bits on the right will disappear. On the left 3 zero bits will be shifted in.

    Hope that helped a bit ... if not shift it out of sight.
  • UltraLazerUltraLazer Posts: 30
    edited 2009-11-20 21:55
    Wow great! thanks for the quick replies guys, this is exactly what I needed.
Sign In or Register to comment.