Does anybody have a quick way to count the number of matching bits in two words?
youngdave
Posts: 70
Dear All
Does anybody have a fast way to count the number of matching bits in two words?
eg
0101000010111101
1011100101010001
6 bits match in these two words.
TIA David Young
Does anybody have a fast way to count the number of matching bits in two words?
eg
0101000010111101
1011100101010001
6 bits match in these two words.
TIA David Young
Comments
Yes, I'm aware of the XOR, but I'm looking for a fast way to count the zeros.
TIA David Young
But for 4 bits, the table is small enough.
The table would look like this:
%0000: 4
%0001: 3
%0010: 3
%0011: 2
%0100: 3
etc ...
shift and mask with %1111, look into the table with the result of the masking, add the 4 numbers of the table's result. You're done.
Or use a shifting mask, TEST and add if the compare is zero.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
I'm really looking for something like the following:
word_XOR_result := word_value1 XOR word_value2
n := 1
repeat while n < 16
if word_XOR_result[noparse][[/noparse]bit#n] = 0
count++
n++
The bit I can't figure out is:
if word_XOR_result[noparse][[/noparse]bit#n] = 0
TIA David Young
Here is a routine that would do what you ask.
Also find enclosed an archive that has a project that uses the method
to illustrate how it works....it uses the Parallax Terminal to enter numbers and output
the result....see the archive.
The method allows you to specify the number and the bits you want to count.
It will return the number of zeros within the bit count of the number.
See how the method is used in the demo program attached
Sam
I just thought that you can make the method even more efficient this way
By the way....this improvement relies on the fact that Result is the default return value
and that it will always be zeroed upon entry into the method.
I think this is true but just in case you can always add a Result~· just above the Repeat.
Regard
Samuel
Post Edited (SamMishal) : 8/26/2009 9:07:44 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lt's not particularly silly, is it?
VAR
word word_value
PUB testa | n, count
number := .................
count := 0
n := 0
repeat while n < 16
if not (word_value & 1)
count++
word_value >>= 1
n++
................. := count
TIA David Young
I think this is the most efficient .... I doubt you can get less code to do this.....
Sam
Post Edited (SamMishal) : 8/26/2009 9:32:11 AM GMT
indent to the correct level.....so your code as given will NOT work....you need to indent
stuff.
Also see what Brad and I have done....just use the METHOD we gave you....
Sam
·
I'm not so sure it is. With my routine you only do one single subtraction at the end of the method. With your "optimisation" you add another constant and xor to each iteration of the loop.
For a loop of 16 bits, your's pushes an additional 14 constants and does an additional 15 math operations.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lt's not particularly silly, is it?
I agree with you when you put that way....
It just looks more elegant with just 3 lines of code...
Sam
Is it fundamentally sound?
PUB Fitness | n, nn, count
n := 1
repeat while n <> Current_Population_Size
nn := 0
repeat while nn <> 15
if not (Chromosome[noparse][[/noparse]n] & 1)
count++
Chromosome[noparse][[/noparse]n] >>= 1
nn++
n++
term.Str(String("Number of zero bits "))
term.dec(count)
term.CarriageReturn
TIA David Young
Those code tags are left square bracket code right square bracket and ending with left square bracket /code right square bracket.
It looks ok at first glance but I'd like to see it properly indented.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lt's not particularly silly, is it?
[noparse][[/noparse]PUB Fitness | n, nn, count]
[noparse][[/noparse] n := 1]
[noparse][[/noparse] repeat while n <> Current_Population_Size]
[noparse][[/noparse] nn := 0]
[noparse][[/noparse] repeat while nn <> 15]
[noparse][[/noparse] if not (Chromosome[noparse][[/noparse]n] & 1)]
[noparse][[/noparse] count++]
[noparse][[/noparse] Chromosome[noparse][[/noparse]n] >>= 1]
[noparse][[/noparse] nn++]
[noparse][[/noparse] n++]
Here is the same idea as before except written in PASM if you ever need it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
- Propalyzer: Propeller PC Logic Analyzer
- BMA: An on-chip PASM Debugger
- SPUD: Spin Source Level Debugger
Post Edited (jazzed) : 8/27/2009 3:39:07 AM GMTWhen you post code in the forum use the # button right above the Editor box while you are editing.
This gives you a box with blue text. You can paste your code in this box and it will show up
with the correct indentation etc.
Your code looks like it might be alright EXCEPT that I cannot tell for sure due to lack of indentation.
As I said before...SPIN CARES A LOT about the indentation
is not the same as
So please repost your code with proper indentation within the box as you see above and then we can tell
if your code is right.
Also you are using
this makes a loop of 16 times. There is a construct in SPIN that allows you to be more efficient. It is
this construct works really well when you have a fixed number of times you need to loop. It avoids having to
use a counter variable and to increment it. Which are two savings.
Also for good programming and ease of changing things later·it is better to put things like 16 in a CONSTANT
in the CON section. This makes it easy for you to later make it a Byte (8) or Long (32) if you need to
So this way you can change the number 16 to 32 and the code will work for 32 bits instead.
In the example above it does not matter since you are using BitCount in only one place. But imagine if you
had BitCount in many places in the code. If you use 16 all over the place and need to change it to 32 later then
you have to change many places. With the constant BitCount all you have to do is change it in ONE place.
Regards
Sam
Post Edited (SamMishal) : 8/27/2009 3:32:54 AM GMT