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
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
Related
I am trying to understand formatted flags of ios stream. Can anyone please explain how this cout.setf(ios::hex | ios::showbase) thing works? I mean how does the or (|) operator work between the two ios formatted flags?
Please pardon me for my bad english.
std::ios_base::hex and std::ios_base::showbase are both enumerators of the BitmaskType std::ios_base::fmtflags. A BitmaskType is typically an enumeration type whose enumerators are distinct powers of two, kinda like this: (1 << n means 2n)
// simplified; can also be implemented with integral types, std::bitset, etc.
enum fmtflags : unsigned {
dec = 1 << 0, // 1
oct = 1 << 1, // 2
hex = 1 << 2, // 4
// ...
showbase = 1 << 9, // 512
// ...
};
The | operator is the bit-or operator, which performs the or operation on the corresponding bits, so
hex 0000 0000 0000 0100
showbase 0000 0010 0000 0000
-------------------
hex | showbase 0000 0010 0000 0100
This technique can be used to combine flags together, so every bit in the bitmask represents a separate flag (set or unset). Then, each flag can be
queried: mask & flag;
set: mask | flag;
unset: mask & (~flag).
This code is what I am using to combine 4 2-bit values (unsigned chars but they only hold values from 0-3) into 1 single unsigned char value
unsigned char nibble = 0;
nibble = (nibble & 0x03) | (output[i] & 0x03);
nibble = (nibble & 0x0C) | (output[i+1] & 0x03) << 2);
nibble = (nibble & 0x30) | (output[i+2] & 0x03) << 4);
nibble = (nibble & 0xC0) | (output[i+3] & 0x03) << 6);
It produces an incorrect value for everything except 00 00 00 00 (it often produces the same result for 2 different sets of 2-bit values).
I'm confused because the code above is an edit of this code, which works fine to combine 2 4-bit values into 1 byte, so why does my version not combine 4 2-bit values into 1 byte?
char byte;
byte = (byte & 0xF0) | (nibble1 & 0xF); // write low quartet
byte = (byte & 0x0F) | ((nibble2 & 0xF) << 4); // write high quartet
I've tried changing 0x03 / 0x0C / 0x30 / 0xC0 to 0xC0 / 0x30 / 0x0C / 0x03, still wrong. Same for changing & 0x03 to & 0xC0.
It's because you clear bits in the nibble each time.
That is, when you say this:
nibble = (nibble & 0xC0)
what you are really saying is "throw away all the work I've done so far, except for the bits at positions 3 and 4".
This code (untested) will probably solve your problem:
unsigned char nibble = 0;
nibble |= (output[i ] & 0x03);
nibble |= (output[i+1] & 0x03) << 2;
nibble |= (output[i+2] & 0x03) << 4;
nibble |= (output[i+3] & 0x03) << 6;
If it's really true that output[i+x] only holds values in the range [0,3], then you can change the code as follows:
unsigned char nibble = 0;
assert(0<=output[i ] && output[i ]<=3)
nibble |= output[i ];
assert(0<=output[i+1] && output[i+1]<=3)
nibble |= output[i+1] << 2;
assert(0<=output[i+2] && output[i+2]<=3)
nibble |= output[i+2] << 4;
assert(0<=output[i+3] && output[i+3]<=3)
nibble |= output[i+3] << 6;
The asserts could, of course, be removed if you're really, really sure. But you can also leave them in and have the compiler extirpate them by using the NDEBUG flag (g++ -DNDEBUG mycode.cpp). See this question for further details.
That's because before populating nibble with the new bits you are filtering it with a mask that if anything does the opposite of what it should do.
nibble = (nibble & 0x03) | (output[i] & 0x03);
nibble = (nibble & 0x0C) | (output[i+1] & 0x03) << 2);
nibble = (nibble & 0x30) | (output[i+2] & 0x03) << 4);
nibble = (nibble & 0xC0) | (output[i+3] & 0x03) << 6);
^^^^ in here you preserve the bits
you want to replace and zero out everything else
Inverting that mask would work:
nibble = (nibble & ~0x03) | (output[i] & 0x03);
nibble = (nibble & ~0x0C) | (output[i+1] & 0x03) << 2);
nibble = (nibble & ~0x30) | (output[i+2] & 0x03) << 4);
nibble = (nibble & ~0xC0) | (output[i+3] & 0x03) << 6);
However, since nibble already starts as 0 anyway, you don't need that. Just populate the bits as in Richard's answer.
User specifies register (LFSR) length with integer as a parameter for a function, for example he enters number 5. I need to initialize this 5-bit length LFSR with all 1 bits (for length 5 it will be 11111) and get a seed mask in a format uint32_t - for 5-length register it will be 0x0001f.
What is the best way to get mask 0x0001f for 5 bit length register when a user enters only length of the register as an integer number 5?
To generate a mask of n bits (where n < 32):
uint32_t mask = (1U << n) - 1U;
Explanation: consider the example where n = 5:
1U << n = 1U << 5 = 0000 0000 0000 0000 0000 0000 0010 0000 = 0x20
then we subtract 1 and get:
0000 0000 0000 0000 0000 0000 0001 1111 = 0x1f
Another option is
std::uint32_t mask = ~(~0U << n);
Also you have to make sure unsigned int isn't less than 32 bits on your system, it may be better to write
std::uint32_t mask = ~(~(std::uint32_t)0 << n);
What do "Non-Power-Of-Two Textures" mean? I read this tutorial and I meet some binaries operations("<<", ">>", "^", "~"), but I don't understand what they are doing.
For example following code:
GLuint LTexture::powerOfTwo(GLuint num)
{
if (num != 0)
{
num--;
num |= (num >> 1); //Or first 2 bits
num |= (num >> 2); //Or next 2 bits
num |= (num >> 4); //Or next 4 bits
num |= (num >> 8); //Or next 8 bits
num |= (num >> 16); //Or next 16 bits
num++;
}
return num;
}
I very want to understand this operations. As well, I read this. Very short article. I want to see examples of using, but I not found. I did the test:
int a = 5;
a <<= 1; //a = 10
a = 5;
a <<= 2; //a = 20
a = 5;
a <<= 3; //a = 40
Okay, this like multiply on two, but
int a = 5;
a >>= 1; // a = 2 Whaat??
In C++, the <<= is the "left binary shift" assignment operator; the operand on the left is treated as a binary number, the bits are moved to the left, and zero bits are inserted on the right.
The >>= is the right binary shift; bits are moved to the right and "fall off" the right end, so it's like a division by 2 (for each bit) but with truncation. For negative signed integers, by the way, additional 1 bits are shifted in at the left end ("arithmetic right shift"), which may be surprising; for positive signed integers, or unsigned integers, 0 bits are shifted in at the left ("logical right shift").
"Powers of two" are the numbers created by successive doublings of 1: 2, 4, 8, 16, 32… Most graphics hardware prefers to work with texture maps which are powers of two in size.
As said in http://lazyfoo.net/tutorials/OpenGL/08_non_power_of_2_textures/index.php
powerOfTwo will take the argument and find nearest number that is power of two.
GLuint powerOfTwo( GLuint num );
/*
Pre Condition:
-None
Post Condition:
-Returns nearest power of two integer that is greater
Side Effects:
-None
*/
Let's test:
num=60 (decimal) and its binary is 111100
num--; .. 59 111011
num |= (num >> 1); //Or first 2 bits 011101 | 111011 = 111111
num |= (num >> 2); //Or next 2 bits 001111 | 111111 = 111111
num |= (num >> 4); //Or next 4 bits 000011 | 111111 = 111111
num |= (num >> 8); //Or next 8 bits 000000 | 111111 = 111111
num |= (num >> 16); //Or next 16 bits 000000 | 111111 = 111111
num++; ..63+1 = 64
output 64.
For num=5: num-1 =4 (binary 0100), after all num |= (num >> N) it will be 0111 or 7 decimal). Then num+1 is equal to 8.
As you should know the data in our computers is represented in the binary system, in which digits are either a 1 or a 0.
So for example number 10 decimal = 1010 binary. (1*2^3 + 0*2^2 + 1*2^1 + 0*2^0).
Let's go to the operations now.
Binary | OR means that wherever you have at least one 1 the output will be 1.
1010
| 0100
------
1110
~ NOT means negation i.e. all 0s become 1s and all 1s become 0s.
~ 1010
------
0101
^ XOR means you turn a pair of 1 and 0 into a 1. All other combinations leave a 0 as output.
1010
^ 0110
------
1100
Bit shift.
N >> x means we "slide" our number N, x bits to the right.
1010 >> 1 = 0101(0) // zero in the brackets is dropped,
since it goes out of the representation = 0101
1001 >> 1 = 0100(1) // (1) is dropped = 0100
<< behaves the same way, just the opposite direction.
1000 << 1 = 0001
Since in binary system numbers are represented as powers of 2, shifting a bit one or the other direction will result in multiplying or dividing by 2.
Let num = 36. First subtract 1, giving 35. In binary, this is 100011.
Right shift by 1 position gives 10001 (the rightmost digit disappears). Bitwise Or'ed with num gives:
100011
10001
-------
110011
Note that this ensures two 1's on the left.
Now right shift by 2 positions, giving 1100. Bitwise Or:
110011
1100
-------
111111
This ensures four 1's on the left.
And so on, until the value is completely filled with 1's from the leftmost.
Add 1 and you get 1000000, a power of 2.
This procedure always generates a power of two, and you can check that it is just above the initial value of num.
What does the following do?
PORTB = (PORTB & ~0xFC) | (b & 0xFC);
PORTD = (PORTD & ~0x30) | ((b << 4) & 0x30);
AFAIK, the 0xFC is a hex value. Is that basically saying 11111100, hence PORTD0-PORTD1 are outputs but the rest are inputs.
What would a full explanation of that code be?
PORTB = (PORTB & ~0xfc) | (b & 0xfc);
Breaking it down:
PORTB = PORTB & ~0xFC
0xFC = 1111 1100
~0xFC = 0000 0011
PORTB = PORTB & 0000 0011
Selects the lower two bits of PORTB.
b & 0xFC
0xFC = 1111 1100
Selects the upper 6 bits of b.
ORing them together, PORTB will contain the upper six bits of b and the lower two bits of PORTB.
PORTD = (PORTD & ~0x30) | ((b << 4) & 0x30);
Breaking it down:
PORTD = PORTD & ~0x30
0x30 = 0011 0000
~0x30 = 1100 1111
PORTD = PORTD & 11001111
Selects all but the 4th and 5th (counting from 0) bits of PORTD
(b << 4) & 0x30
Consider b as a field of bits:
b = b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0
b << 4 = b3 b2 b1 b0 0 0 0 0
0x30 = 0011 0000
(b << 4) & 0x30 = 0 0 b0 b1 0 0 0 0
ORing the two pieces together, PORTD will contain the 0th and 1st bits of b in its 4th and 5th bits and the original values of PORTD in the rest.
The first line actually sets the state of port's PB7-PB2 lines. The current state of PORTB is first masked using ~0xFC = 0x03, so all bits, but 0 and 1, are reset.
The second step is masking b using 0xFC, so bits 0 and 1 are always 0. Then the values are OR'ed together. Effectively, it sets PB7-PB2 from b[7]..b[2], while keeping the current state of PB1 and PB0 untouched.
Note, that the PORTB register bits serve different purposes depending on the pin direction configured via the DDRB register. For output pins, it simply controls the pin state. For input pins, PORTB controls the pin's pull-up resistor. You have to enable this pull-up resistor if, for example, you have a push button connected between the pin and ground - this way the input pin is not floating when the switch is open.