Peter Nachtwey
Member
I have watched for many years how people come up with ways of finding the bit numbers of bits that are set. RSLogix5000 has a FBC which works and that is good enough for most cases but what do you do if you don't have a FBC inctruction? I have seen people shift bits right until the carry is set and I have seen people shift a 1 left and count how many times they must shift but that takes time and worse yet it is a loop. What is needed is a good way to find the bit number of a set bit that is simple and doesnt't require looping or floating point. One shouldn't use floating point because it actually is doing a lot of work when executing ln() and exp() functions.
To find the index or number of a bit set one must first reduce the set of bits to just one. It is easy to find least significant bit set in a register of bits.
This takes just one rung or maybe two depending on the PLC.
The next trick is to find the bit number of the bit set. This too is easy but it takes a few more rungs but at least it doesn't require looping.
If more than one bit is set then isolate the bit
Now there is only one bit set in dintBit.
Find the bit number or index using the follow procedure:
A PLC should be able to implement this in 6 rungs. A S7 should be very efficient.
This can be extended by adding another check for 64 bit registers. There are 64 bit Power PC, AMD and Intel processors.
Does it make any difference what order the bits are tested?
One can see this is much faster than looping or shifting a bit left. I didn't see any reason to post this before because I thought all PLCs had ENCode and DeCoDe instructions.
Don't lose this.
To find the index or number of a bit set one must first reduce the set of bits to just one. It is easy to find least significant bit set in a register of bits.
This takes just one rung or maybe two depending on the PLC.
The next trick is to find the bit number of the bit set. This too is easy but it takes a few more rungs but at least it doesn't require looping.
If more than one bit is set then isolate the bit
Code:
dintBit = dintBits and ( not dintBits + 1 )
Find the bit number or index using the follow procedure:
Code:
BitNumber = 0
if ( dintBit and 0AAAAAAAAH <> 0 )
BitNumber = BitNumber + 1
if ( dintBit and 0CCCCCCCCH <> 0 )
BitNumber = BitNumber + 2
if ( dintBit and 0F0F0F0F0H <> 0 )
BitNumber = BitNumber + 4
if ( dintBit and 0FF00FF00H <> 0 )
BitNumber = BitNumber + 8
if ( dintBit and 0FFFF0000H <> 0 )
BitNumber = BitNumber + 16
This can be extended by adding another check for 64 bit registers. There are 64 bit Power PC, AMD and Intel processors.
Does it make any difference what order the bits are tested?
One can see this is much faster than looping or shifting a bit left. I didn't see any reason to post this before because I thought all PLCs had ENCode and DeCoDe instructions.
Don't lose this.