How can I set a digit in a hexadecimal number? I currently have this code:
int row = 0x00000000;
row |= 0x3 << 8;
row |= 0x2 << 4;
row |= 0x1 << 0;
printf("Row: 0x%08x", row);
Which works perfectly fine as long as "row" is just zeros. As soon as I change it to something like this:
int row = 0x33333333;
row |= 0x3 << 8;
row |= 0x2 << 4;
row |= 0x1 << 0;
printf("Row: 0x%08x", row);
I just get this output:
Row: 0x33333333
Hexadecimal is the name of the numbering system that is base 16. This system, therefore, has numerals 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, and 15. That means that two-digit decimal numbers 10, 11, 12, 13, 14, and 15 must be represented by a single numeral to exist in this numbering system.
The conversion of hexadecimal to decimal is done by using the base number 16. The hexadecimal digit is expanded to multiply each digit with the power of 16. The power starts at 0 from the right moving forward towards the right with the increase in power. For the conversion to complete, the multiplied numbers are added.
Hexadecimal numbers are represented by only 16 symbols. These symbols or values are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E and F.
Also, since 16 in the decimal system is the fourth power of 2 ( or 24 ), there is a direct relationship between the numbers 2 and 16 so one hex digit has a value equal to four binary digits so now q is equal to “16”.
You should delete (make it 0) the digit first.
row &= ~(0xf << 4);
~
operator reverses the values of all bits in the number. So. 0x000000f0
becomes 0xffffff0f
.
Your code should look like:
row &= ~(0xf << 8);
row |= 0x3 << 8;
row &= ~(0xf << 4);
row |= 0x2 << 4;
row &= ~(0xf << 0);
row |= 0x1 << 0;
As Alexandru explained, you do need to clear the bitfield you're trying to set before you go on to set it.
Just to add further comment on why your code didn't do what you wanted, consider what is happening to the variable at the binary level:
row |= 0x2 << 4;
The |= operator is a "bitwise or". Hence if either the bit you're trying to set OR the bit you're passing in is set to 1, the result is 1. In your code, row is set to 0x33333333, so each 4 bit hexadecimal digit is 0011 in binary. When you bitwise or that with 0x2, you get 0x3:
/* 0x3 | 0x2 = 0x3 */
0011 | 0010 = 0011
If you clear the bitfield first, you get 0x2, which is what you want:
/* 0x3 | 0x0 = 0x0 */
0011 | 0000 = 0000
/* 0x0 | 0x2 = 0x2 */
0000 | 0010 = 0010
Note that data manipulation using shifts and bitwise operations is unlikely to be portable between different platforms. You may run into problems trying to run code relying on bit shifts on machines of different endianess, or indeed if you try to run code that works on a 32 bit machine on a 64 bit machine:
http://www.viva64.com/en/a/0004/#ID0EQFDI
Wikipedia has more on bitwise operations:
http://en.wikipedia.org/wiki/Bitwise_operation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With