Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
If i'm using m instead of ~m then the code gives me the expected hexadecimal value of 32 but here it's giving ffffffdf as output.
EDIT
I know how bitwise ~ NOT operator works. But i'm not understanding this.Could somebody explain this...??
#include<stdio.h>
int main()
{
unsigned int m = 32;
printf("%x\n", ~m); //ffffffdf is printed as output
return 0;
}
Every hexadecimal digit is four bits. Since you got 8 hexadecimal digits your integers seems to be 8*4=32 bit.
The NOT of 32 = 000000000000000000000000000010000 would be something like 11111111111111111111111111101111 which would be the hexadecimal digits above.
In C, ~ is the bitwise-not operator. You said you understand how this operator works, but your question indicates that you do not. So let's go through this example:
First, you declare m to be an unsigned int, which happens to be 32 bits wide on your platform. You assign it the decimal value 32. The variable m is 0x00000020.
Then, you print it out. When you print it out normally, the expected output appears. But when you print it out with the ~ operator, you get something completely different.
The ~ (bitwise-not) operator does exactly what it says on the tin: It negates (flips) every bit, so 1s become 0s and 0s become 1s. Let's see what that would do to your number:
m = 0b00000000000000000000000000100000 = 0x00000020
~m = 0b11111111111111111111111111011111 = 0xffffffdf
As you can see, the result exactly matches what is being output, which is good -- it means both your compiler and CPU are working as expected!
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to merge two characters and print them via a single variable by using ASCII (refer to the image below):
[1]: https://i.stack.imgur.com/TWodP.jpg
try this if your machine is little endian
unsigned int C = (b << 8) | a;
printf("%s",&C);
otherwise if your machine is big endian try
unsigned int C = (a << 24) | (b<<16);
printf("%s",&C);
Based on my comment, but improved by Jonathan's input, I propose to do this:
int C;
C= (((unsigned char)a)<<8)|((unsigned char)b);
You have already tried the commented version to be helpful, this one is basically the same, just being robust against potentially negative values of a and b (which I considered out of scope, but Jonathan is right in being as safe as possible).
As for the explanation:
The << 8 part, a so-called bitshift left, moves a value by 8 bit towards the MSBs.
I.e. a 00000000010000001 becomes a 01000000100000000.
To be safe from negative value (see below why that is important), the value is first type-casted to unsigned char. That is the part ((unsigned char)a). Note that I tend to be generous when it comes to using (), some people do not like that. This is done for both values.
With values 'A' and 'B' we end up with
0100000100000000 and
0000000001000010.
The next part uses a bitwise OR (|), in contrast to a logical OR (||).
The result is
0100000101000010, which is what I understand to be your goal.
The importance of protecting against negative input is this. Any negative 8bit value has the MSB set and when cast to a wider data type will end up with all 8 new high bits set. This is because of the representation of negative values in integers in 2-compliment.
The final conversion to the desired wider data type is as Jonathan explains:
If you have (unsigned char)A << 8 as a term, then the unsigned char value is extended to int before the shift occurs, and the result is an int.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm receiving the following data over a serial port: <0x1b><0x2e><0x15>...
Each value enclosed in '<>' is a single byte.
I require the third byte from the data so i do this:
int Length;
char Data[..];
Length = Data[2];
But the value of Length is 21 and not 15 because the value written in memory is hex.
How do i convert the decimal representation of 15 to decimal 15?
I've tried converting it to various types and so on..
But none of that works for me as i'm writing a driver and performance matters a lot.
I've looked over stackoverflow and other sites but all the given examples are with strings, none are with plain integers.
When i send it to the rest of the algorithm i run into issues as the algorithm expects 15.
Given int x that contains 8 bits that represent a number using natural packed binary-coded decimal, they can be converted to the number with:
int y = x/16*10 + x%16;
x/16 produces the high four bits, and then multiplying by ten scales them to the tens position. x%16 produces the low four bits. They are kept in the ones position and added to the tens.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Suppose I have the number 0b000 and I need to set the correct bits, so that they will be equal for ex. 5. (0b101).
How do I do that, using bitwise operations algorithm?
Okay, more details then. I'm developing morse code decoder, and to describe a input, I'm using 8 bits: 000 00000, where first three bits are the number of dot/dashes given, and the rest of bits are reserved for the input, where dot is 0, and dash is 1.
For example, the letter A (.-) would be: 010 01000.
The question is, how can I modify the first three bits so that they will show how many dot/dashes were given during the input?
You switch bits on using |. Let's stick with your non-standard notation for binary literals (note that C++14 onwards supports it):
0b000 | 0b100 is 0b100.
0b100 | 0b001 is 0b101.
Note that you can toggle bits using ^ (work through some examples as an exercise).
Finally, you can switch off bits using '&~`.
Solved, if you want to set the first 3 bits, then shift 5 bits to the left (where value is the number you want to set on 3 first bits):
value = value << 5;
And then OR it with the rest of bits:
morseBits = morseBits | value;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I wonder is there anyway to get the first 2 most significant bits of a binary number version of a decimal number without converting it to actually binary number. For example, I want to get "00" from 5 which is "00101" in binary. Does c supports this binary conversion in an easy way? Does c support shifting and bit masking etc?
Thanks
Yes it does!
So to get the first 2 bits from an 8-bit number we need to mask your current number.
We can do this:
some_number = some_number & 0xC0;
some_number &= 0xC0; // This does the same thing with a different syntax
So what we're doing here is performing a bitwise AND with the value 0xC0, converting 0xC0 to binary gives us 1100 0000. So when we AND this value with some_number we get ONLY the top 2 bits as every other value in the number is 0 and so produces a 0 whenever we AND it with anything else.
For numbers larger than 8-bit all we have to do is increase the length of our mask.
Here's another example say we want the top 2 bits of a 32 bit integer
some_number = some_number & 0xC00000
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
According to text:
"In rare case of C/C++ compiler that does not perform sign extension on right shift of a negative number, the trick to shift right to divide the number fails"
Consider the following example:
unsigned int i = 0b10000000; // 128
i = i >> 1; // i equals 01000000 i.e. 64
That is the only way I know to block sign extension. Also, by adding unsigned it becomes a positive number so please correct.
Sign extension on bitwise right-shift of negative number is implementation-defined in C. It means it is up to the compiler to decide if it performs the sign propagation and the compiler documentation has to document the selected behavior.
From the C Standard:
(C99, 6.5.7) "If E1 has a signed type and a negative value, the resulting value is implementation-defined."
Among compilers, gcc always propagates the sign:
Signed `>>' acts on negative numbers by sign extension.
http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html