Hello again.
I never got around to thank you for taking time to explain to me.
If you're not already a teacher, you should be.. :-)
I've never found an easy explaination like you wrote.
Now my program is up an running, at least the "alpha" version.
Again thank you!
I hope I can return the favor some day.
Regards,
Oyvind Eriksen
"Barry Kelly" <barry.j.kelly@gmail.com> wrote in message
news:38mt929ssuiif635v5uov3gjvu5oli378e@4ax.com...[color=blue]
> "Oyvind Eriksen" <oyvind -(at)- eriksen.cn> wrote:
>[color=green]
>> Thank you so much!
>> Can you explain how that code works? Or send me to a website that
>> explains
>> that?
>> I'm somewhat new to C# and haven't figured out the consept you used and
>> I'm
>> eager to learn.[/color]
>[color=green][color=darkred]
>> > ---8<---
>> > static int GetBits3(byte b, int offset, int count)
>> > {
>> > return (b >> offset) & ((1 << count) - 1);
>> > }
>> > --->8---[/color][/color]
>
> You've got a set of bits in memory that look like this:
>
> 00000000
>
> The offset is zero-based, and starts counting from the right.
> The count is the number of bits to get. For a (offset, count) of (2,4),
> you'd be trying to get these bits:
>
> GGxxxxGG
>
> (I'm using 'xxxx' to represent the bits you're trying to get at, and G
> to indicate Garbage that we don't want in the result.)
>
> The three operations used in the code above are >> (shift right), <<
> (shift left) and & ("AND" or "mask").
>
> The first step is to move the interesting bits to the right until they
> start at offset zero. So, we shift the bits to the right with shift
> right (>>) offset times:
>
> GGxxxxGG >> offset => 00GGxxxx
>
> So now we have all our interesting bits positioned from 0..count-1
> (counting bits from the right-most place). (0 got shifted in from the
> left, because byte is an unsigned number.)
>
> The next thing to do is to remove any uninteresting bits that extend to
> the left of our bitfield. For example, the original byte might look like
> this:
>
> 01001011
>
> after shifting by 2, it would look like:
>
> 00010010
> ____^^^^___ interesting bits
>
> You can see here that any bits left over, to the left of our interesting
> bits, would corrupt our result. So, we need to mask them out with the &
> operator (the "and" operator).
>
> The value we'd like to use to mask these bits out is "count '1's". For a
> count of 4, we need 1111; for a count of 6, we'd need 111111. So, for
> our count of 4, we'd like to perform this mask operation:
>
> 00GGxxxx
> 00001111 &
> --------
> 0000xxxx
>
> This removes the garbage because any number and'd with '0' produces 0.
>
> So, the only question is how to turn 'count' into our mask. The way this
> is done is simple: every power of two is one more than the sum of the
> previous positive powers of two.
>
> For example consider 8, which is 2^3:
>
> 2^0 + 2^1 + 2^2 + 1
> = 1 + 2 + 4 + 1 = 8
>
> Look at it another way, in binary. Every power of 2 in binary consists
> of exactly one digit:
>
> 2^0 = 1 = 1
> 2^1 = 2 = 10
> 2^2 = 4 = 100
> 2^3 = 8 = 1000
> 2^4 = 16 = 10000
>
> What happens when you subtract 1 from these powers of two? You end up
> with all the 0's to the right of the 1 becoming 1:
>
> 2^0 - 1 = 0 = 0
> 2^1 - 1 = 1 = 1
> 2^2 - 1 = 3 = 11
> 2^3 - 1 = 7 = 111
> 2^4 - 1 = 15 = 1111
>
> So, here's where the << operator comes in. Shift 1 left by count times,
> and you get 2^count. For example, 2^3 = 1 << 3:
>
> 1 << 3 = 1000 = 8
>
> So, hopefully you can see where it all comes together. 1 << count is
> 2^count, and when you subtract 1, that makes all the lesser bits 1 -
> which is exactly what we want out of the mask. Getting back to our byte:
>
> 00GGxxxx
>
> Our count is 4, so we take 1 << 4:
>
> 00010000
>
> And we subtract one:
>
> 00001111
>
> This is the mask that's used with earlier, shifted number:
>
> 00GGxxxx
> 00001111 &
> --------
> xxxx
>
> This mask works because any digit AND'd with 1 remains unchanged.
>
> OK. No more homework for me unless I go back to college :)
>
> -- Barry
>
> --
>
http://barrkel.blogspot.com/[/color]