i would just like to everyone that i now understand bitwise operators or anything bitwise in C
woohoo took me a while, but then it just hit me today while i was reading a C book in the lawn of my college... yahoo! lol okay i'm just proud of myself!
sorry i wasted a thread for this! i'm just giddy
gtsphere
bitwise operators!
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:bitwise operators!
great job! Kernighan & Ritchie will be proud of you
Re:bitwise operators!
With a thread title like this one, some newbs are going to want to look in here... and what do they find? Someone says "I know bitwise operators"!
Now, to help the newbies to OS developement who need to know this stuff:
*** BIT OPERATIONS STUFF ***
x << 3; Shifts x over to the left 3 bits. Basically an x * 2^3. x << 4 would be like x * 2^4.
x >> 3; Shifts x over to the right 3 bits. Basically an x / 2^3. x >> 4 would be like x / 2^4.
x & 0xF; This masks out the lowest (right most) 4 bits in a number and erases the rest. Meaning If you have a number like 60 (0b00111100) would become 12 (0b00001100)
x | 0xF; This takes a variable and sets the lower 4 bits to on. 60 (0b00111100) would become 63 (0x00111111)
If you want, you don't need to use 0xF. You could use 0x8 which would only save/set the bit in position 4 of 8.
What's good about these bitops is that they typically can be performed in 1 or 2 clock pulses. For example, if you CPU runs a 500MHz, you can do 250million to 500million bitops per second. Bitops can be used to make multiplication take only 2 clock pulses(shift - multiply by power of 2), instead of doing a multiply which could take about 20 clocks...
Now, to help the newbies to OS developement who need to know this stuff:
*** BIT OPERATIONS STUFF ***
x << 3; Shifts x over to the left 3 bits. Basically an x * 2^3. x << 4 would be like x * 2^4.
x >> 3; Shifts x over to the right 3 bits. Basically an x / 2^3. x >> 4 would be like x / 2^4.
x & 0xF; This masks out the lowest (right most) 4 bits in a number and erases the rest. Meaning If you have a number like 60 (0b00111100) would become 12 (0b00001100)
x | 0xF; This takes a variable and sets the lower 4 bits to on. 60 (0b00111100) would become 63 (0x00111111)
If you want, you don't need to use 0xF. You could use 0x8 which would only save/set the bit in position 4 of 8.
What's good about these bitops is that they typically can be performed in 1 or 2 clock pulses. For example, if you CPU runs a 500MHz, you can do 250million to 500million bitops per second. Bitops can be used to make multiplication take only 2 clock pulses(shift - multiply by power of 2), instead of doing a multiply which could take about 20 clocks...
Re:bitwise operators!
Perhaps a clarification of the clarification would help, especially for the C impaired.
In addition to the boolean logical operators, C possesses a matching set of bitwise logical operators. When applied to a value (which can be signed or unsigned of char, short, int, long), it performs the appropriate logical comparison on each bit of the two arguments. They are more or less equivalent to the logical assembly instructions available in most CPUs (specifically, the bitwise-assignment operators such as "x ^= y" match the assembly operations found on the PDP-11, the system C was designed on).
For those who really are lost, here's a quick review of the bitwise operations. Assuming
[tt]
typedef byte unsigned char;
byte m, n, x, y, z;
int i = 2;
x = 0xB5; /* binary 10110101 */
y = 0x68; /* binary 11011000 */
m = 0xFB; /* binary 11111011 - mask with bit 2 cleared */
n = 0x08; /* binary 00001000 - mask with bit 3 set */
[/tt]
and that bits are counted "76543210", then the operators can be described as follows:
[tt]
NOT
C: ~x;
x86 assembly: NOT x (matches x = ~x)
result:
10110101 == 01001010
Not simply reverses the bit pattern, i.e., clears any set bit and sets any cleared bit.
AND
C: x & y
x86 assembly: AND x, y (matches x &= y, which means "AND x and y and assign the value to x")
result:
x = 0xB5 = 10110101
y = 0x68 = 11011000
-- = ---- = --------
z = 0x20 = 10010000 -> only those bit which are set in both
x &= m is often used to clear a specific bit in x, by having m hold a 'mask' in which every bit except the one to cleared is set. This clears the one target bit while preserving the rest of the bits in x. For example, to clear bit 2 in x:
10110101
11111011
--------
10110001 -> only bit 2 was changed
OR
C: x | y
x86 assembly: OR x, y (matches x |= y)
result:
10110101
11011000
--------
11111101 -> set every bit that is set in either of the bitfields
Just as x &= m can be used to clear a bit, x|= n can be used to set one, in this case bit 3:
10110101
00001000
--------
10111101 -> only bit 3 was changed
Exclusive OR
C: x ^ y
x86 assembly: XOR x, y (matches x ^= y)
result:
10110101
11011000
--------
01101101 -> set bits that are set in exactly one of the bitfields
x ^= n can be used to toggle bit values, switching them set to clear or clear to set. For example:
10110101
00001000
--------
10111101 -> bit 3 was set
00001000
--------
10110101 -> bit 3 was cleared again
[/tt]
Assembly programmers should note that the x86 instruction set incudes special instructions (BTS, BTR, and BTC) for setting, clearing and toggling individual bits, respectively. However, these instructions are actually slower than the general bitwise operators, and meant mostly for use in conjunction with the LOCK prefix as primitives for mutual exclusion.
And just to confuse you, I could point out that, in signed two's-complement arithmetic,
-i == 1 + (^i)
that is,
-2 == 11111110 == 11111101 + 1
Or to put it in terms of x86 assemby language,
NEG i
can be replaced with
NOT i
INC i
But I'm sure you alread knew that.
HTH. C&CW.
In addition to the boolean logical operators, C possesses a matching set of bitwise logical operators. When applied to a value (which can be signed or unsigned of char, short, int, long), it performs the appropriate logical comparison on each bit of the two arguments. They are more or less equivalent to the logical assembly instructions available in most CPUs (specifically, the bitwise-assignment operators such as "x ^= y" match the assembly operations found on the PDP-11, the system C was designed on).
For those who really are lost, here's a quick review of the bitwise operations. Assuming
[tt]
typedef byte unsigned char;
byte m, n, x, y, z;
int i = 2;
x = 0xB5; /* binary 10110101 */
y = 0x68; /* binary 11011000 */
m = 0xFB; /* binary 11111011 - mask with bit 2 cleared */
n = 0x08; /* binary 00001000 - mask with bit 3 set */
[/tt]
and that bits are counted "76543210", then the operators can be described as follows:
[tt]
NOT
C: ~x;
x86 assembly: NOT x (matches x = ~x)
result:
10110101 == 01001010
Not simply reverses the bit pattern, i.e., clears any set bit and sets any cleared bit.
AND
C: x & y
x86 assembly: AND x, y (matches x &= y, which means "AND x and y and assign the value to x")
result:
x = 0xB5 = 10110101
y = 0x68 = 11011000
-- = ---- = --------
z = 0x20 = 10010000 -> only those bit which are set in both
x &= m is often used to clear a specific bit in x, by having m hold a 'mask' in which every bit except the one to cleared is set. This clears the one target bit while preserving the rest of the bits in x. For example, to clear bit 2 in x:
10110101
11111011
--------
10110001 -> only bit 2 was changed
OR
C: x | y
x86 assembly: OR x, y (matches x |= y)
result:
10110101
11011000
--------
11111101 -> set every bit that is set in either of the bitfields
Just as x &= m can be used to clear a bit, x|= n can be used to set one, in this case bit 3:
10110101
00001000
--------
10111101 -> only bit 3 was changed
Exclusive OR
C: x ^ y
x86 assembly: XOR x, y (matches x ^= y)
result:
10110101
11011000
--------
01101101 -> set bits that are set in exactly one of the bitfields
x ^= n can be used to toggle bit values, switching them set to clear or clear to set. For example:
10110101
00001000
--------
10111101 -> bit 3 was set
00001000
--------
10110101 -> bit 3 was cleared again
[/tt]
Assembly programmers should note that the x86 instruction set incudes special instructions (BTS, BTR, and BTC) for setting, clearing and toggling individual bits, respectively. However, these instructions are actually slower than the general bitwise operators, and meant mostly for use in conjunction with the LOCK prefix as primitives for mutual exclusion.
And just to confuse you, I could point out that, in signed two's-complement arithmetic,
-i == 1 + (^i)
that is,
-2 == 11111110 == 11111101 + 1
Or to put it in terms of x86 assemby language,
NEG i
can be replaced with
NOT i
INC i
But I'm sure you alread knew that.
HTH. C&CW.