Why does this bitshifting work? (for printing numbers as binarys) - c

I saw the code and was wondering why this is working:
#include <stdio.h>
void printBinary (unsigned int number)
{
unsigned int mask = 0;
for(mask = 1 << 31; mask!=0; mask >>=1)
{
if (number & mask)
printf("1");
else
printf("0");
}
printf ("\n");
}
int main()
{
printBinary (10);
return 0;
unsigned int suffix = 24;
return 0;
}
I imagine the void function like this:
at first we have
mask: 100000000000000... (32times zero) and
number: 0000000000000000000001010
the it compares both numbers with & and they are different, so 0 is posted.
next loop:
01000000000....
0000000000000000000001010
same here. When it comes to
00000000000000001000
00000000000000001010
(number & mask) will be true, but still both numbers are differnt. It's like it is only comparing that the binary numbers where the 1 currently is in the upper number. But since mask and number as such is compared it should only print 1 if they are completely the same. So what I don't understand is why a 1 is printed here instead of a 0. I think a 1 should only be printed if it's
0000000000000001010
0000000000000001010
I hope it is clear what my question is, maybe someone can explain to me how this loop works in detail.
Thanks!

& is a bitwise AND operation, so
00000000000000001000 & 00000000000000001010
evaluates to
00000000000000001000
which is different from 0, and in C
if (number & mask)
is shorthand for
if ((number & mask) != 0)

The work is done by this algorithm:
for(mask = 1 << 31; mask!=0; mask >>=1) {
if (number & mask)
printf("1");
else
printf("0");
}
The first thing to understand is the "mask" - the mask here is a 32-bit integer with EXACTLY 1 bit set to 1 and all the others are zero. You seem to have understood that the mask starts as "1000000...000" and on each successive loop, the "1" in the mask is shifted to the right (mask >>= 1). So the sequence on successive loop iterations is: "01000....000", "001000...000", ... "0000... 00010", "0000...00001"
The next thing is the "&" operator - "bit-wise AND" - when 2 numbers are "bit-wise AND"ed together, the result will have 1 bits ONLY in positions where both the inputs had 1 bits. So, for example, "00010" & "11010" == "00010". Since your "mask" only has 1 bit set, the result of (number & mask) will be identical to the mask itself if the bit in that same positiion in number is a 1 and will be 0 if not.
Lastly, we note that in C, 0 is false and ANYTHNG else is considered true.
Thus, we can read the loop above as follows:
For each bit from position 31 to position 0:
if that bit is a 1 in the number:
print 1
else:
print 0
Voila - the number is printed in its binary form.

the bitwise AND (&) result is a number in which all the bits that were set (1) in the 2 operands, are set.
this means that if a single bit matches, just as you observed, the result will be a non-zero number, which evaluates to TRUE

Your analysis of the code is pretty much correct.
However you have not quite understood how the bitwise & operator works.
The output of & for 2 bits is given by this table
bit 2
1 0
____
bit 0|0 0
1 1|1 0
For bigger numbers the & compares the bit at the same index in each number in turn and produces an output based on table above so you only get a 1 in the output if there is a 1 in the same location in both inputs. So for your example numbers you get
00000000000000001000 //input 1
00000000000000001010 //input 2
00000000000000001000 //output
Now any non zero number equates to true so the if statement will enter the print "1" case. I prefer the more explicit code
if( (number & mask) != 0 )
Basically all the loop is doing is working through the number a bit at a time and testing if it is 1 or zero and printing the corresponding character.

Related

C program to find required number of bits for a given number [closed]

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 4 years ago.
Improve this question
I am new at programming and trying to understand the following program.
This program gets the minimum number of bits needed to store an integer as a number.
#include <stdio.h>
/*function declaration
* name : countBit
* Desc : to get bits to store an int number
* Parameter : int
* return : int
*/
int countBit(int);
int main()
{
int num;
printf("Enter an integer number :");
scanf("%d",&num);
printf("Total number of bits required = %d\n",countBit(num));
return 0;
}
int countBit(int n)
{
int count=0,i;
if(n==0) return 0;
for(i=0; i< 32; i++)
{
if( (1 << i) & n)
count=i;
}
return ++count;
}
Can you please explain how the if( (1 << i) & n) condition works?
To begin you should read up on Bitwise Operators.
for(i=0; i< 32; i++)
{
// Check if the bit at position i is set to 1
if( (1 << i) & n)
count=i;
}
In plain english, this is checking what the highest position of all "set" bits is.
This program gets the minimum number of bits needed to store an integer as a number.
Getting the position of the largest "set" bit will tell us how many bits we need to store that number. If we used a lesser amount of bits, then we would be reducing our maximum possible number to below our desired integer.
"<<" and "&" are bitwise operators, that manipulate a given (usually unsigned integer) variable's bits. You can read more about such operators here. In your case,
1<<i
is the number whose binary representation is 1 followed by i-1 zeroes (and preceded only by zeroes as well). Overall, the check
(1<<i)&n
evaluates to true if the i-th bit of the variable n is 1, and false otherwise, and therefore the loop finds out what is the leftmost bit which is 1 in the given number.
Its very simple if you understand bitwise operators.
Shift operator: <<is a left shift operator, which shifts a value by designated bits. In C, x << 1, will shift x by 1-bit.
Lets just consider 8-bit values for now and lets say x is 100 in decimal, 0x64 in Hexadecimal numbering system and binary representation of the same would be 0110 0100
Using the shift operator, lets shift this value 1-bit. So,
0 1 1 0 0 1 0 0
becomes
0 1 1 0 0 1 0 0 0
^ ^
Discarded Padded
as the last (right extreme) bit will be padded with a 0.
The number becomes, 0xC8, which is 200 in decimal numbering system, which is double the previous value!
The same goes for a >> operator, try it yourselves if you haven't. Result should be the half, except for when you try to 0x01 :-)
As a side note, when you'll grow up and start looking at the way shell/console is used by developers, you'll understand that > has a different purpose.
The & operator: Firstly, && and & is different. First one is a logical operator and the latter one is a bitwise operator.
Lets pick a number again, 100.
In logical and operation, the end result is always true or false. For example, 0x64 && 0x64 will result in a true condition, all other combinations will result in a false result.
But, the bitwise and operation, is used this way: Is the ith bit of 0x64 set? If yes, results in true, else results in false.
The if statement:
if( (1 << i) & n)
is doing just that. For every iteration of loop, it left shifts 1 by i bits, and then checks if the ith bit of n is set, results in true if set, else results in false.
Programmers usually use a macro for this, which makes it more readable.
#define CHECK_BIT(value, position) ((value) & (1 << position))

Decimal to binary using Bitwise operator

#include <stdio.h>
int main()
{
int decimal_num, c, result;
printf("Enter an integer in decimal number system\n");
scanf("%d", &decimal_num);
for (c = 31; c >= 0; c--)
{
result = decimal_num >> c;
if (result & 1)
printf("1");
else
printf("0");
}
printf("\n");
return 0;
}
This code takes a decimal number and converts it into binary using bitwise operator. I am having a hard time understanding the logic inside the for loop result = decimal_num >> c and why does it iterate from for (c = 31; c >= 0; c--). I understand the basics of bitwise AND, OR, XOR and NOT and I know that when an odd number is ANDED with '1' the result is '1' else '0'(because the least significant bit of all odds are 1).
Here's an explanation of the code :
The program scans the bitwise representation of the decimal digit from left to write, working on each bit. The decimal digit is supposed to have 32 bits, hence the for loop runs 32 times.
The first time, the value of c is 31.
Assuming the bit representation of decimal_num initially is
x................................ ( . represents any digit )
decimal_num >> 31 shifts all bits rightwards 31 times, such that the first bit is shifted at the right most end. The result is 0000000000000000000000000000x. Note that when digits are shifted, 0 is pre-pended to the left end.
The result is then checked to see if it was 0 or 1, and printed accordingly.
0000000000000000000000000000x & 00000000000000000000000000001 = 1 if x is one
0000000000000000000000000000x & 00000000000000000000000000001 = 0 if x is zero.
Moving on, and checking the second bit when c is 30. :
.Y..............................
decimal_num >> 30 results in
000000000000000000000000000000.Y
000000000000000000000000000.Y & 00000000000000000000000000001 = 1 if Y is one
000000000000000000000000000.Y & 00000000000000000000000000001 = 0 if Y is zero.
We go on printing the results until the last digit.
Hope this helps you understand.

A bit value verification

I want to verify two bits (for example the bit number 3 and 5) values of a uint8
if their value is 0, I want to return 1
uint8 a;
if ((a & !(1<<3)) && (a & !(1<<5)))
{
Instructions..
}
Is this code correct ?
No, your code won't work in way that you want. ! operator results only in 0 or 1 and info about actual non-zero bit is lost anyway. You may use something like this:
if(!(a & ((1 << 3) | (1 << 5))) {
/* ... */
}
At first stage you are creating mask with | operator. This mask has non-zero bits only at positions that you are interested in. Then this mask is combined with tested value via &. As result you get 0 only if value has zero bits at tested positions. And then just inverse 0 to 1 with ! to obtain true condition.
It is not correct.
The ! operator is boolean NOT, not a bitwise NOT.
So, if you want to check if bits 3 & 5 are both zeroes you should write:
uint8 a;
...
if (!(a & (1<<3)) && !(a & (1<<5)))
{
Instructions..
}
Further optimisation of the expression in if is possible.
This is trivial if you don't attempt to write it as a single, messy expression. There is no advantage of doing so - contrary to popular belief, mashing as many operators into a single line is actually very bad practice. It destroys readability and you gain no performance benefits what-so-ever.
So start by creating a bit mask:
uint8_t mask = (1<<3) | (1<<5);
(The parenthesis are actually not needed, but not everyone can cite the C operator precedence table in their sleep, so this is recommended style.)
Then check the data against the mask:
if(data & mask) // if any bit contains value 1
return 0;
else // if no bit contains value 1
return 1;
Which, if you will, can be rewritten as a boolean expression:
return !(data & mask);
The complete function could look like this:
bool check_bits (uint8_t data)
{
uint8_t mask = (1<<3) | (1<<5);
return !(data & mask);
}
Your expression is false, you should not negate the masks this way and you must ignore other bits so don't use a negation. Simply:
(a & (1<<3)) + (a & (1<<5))
gives 0 if both are 0s.
Assuming that a actually is initialized, then the expression will not work as you expect. The logical not operator ! gives you a one or a zero (boolean true or false), which you then use in a bitwise and operation. That will not give you the correct result.
I suppose you mean to use the bitwise complement operator ~ instead, as in ~(1 << 3). Not that it would work anyway, as that will just check that any of the other bits in a is non-zero.
Instead check if the bit is one, and then turn around the logic using the logic not operator !, as in !(a & 1 << 3).
No. ! operator does logical negation, and since 1<<3 is not zero, !(1<<3) is zero. It means a & !(1<<3) will always be zero and therefore the condition will never be true.
I think masking is one of good ways to do what you want to do.
uint8 a;
/* assign something to a */
return (a & ((1 << 3) | (1 << 5))) == 0;
a & ((1 << 3) | (1 << 5)) is a value in which the 3rd and 5th bit (0-origin) of a keep their original value and all other bits is turned to zero. Checking if the value is zero means checking if all of the bits to check are zero while not careing other bits. == operator will return 1 if two operands are equal and 0 otherwise.
If you want to test for some combination of BIT_A and BIT_B (or whatever number of bits you can have) You can do this:
#define BIT_A (1 << 3)
#define BIT_B (1 << 5)
...
#define BIT_Z (1 << Z)
...
/* |here you put all bits |here you put only the ones you want set */
/* V V */
if (a & (BIT_A | BIT_B | ... | BIT_Z) == (BIT_A | ... | BIT_I | ...))
{
/* here you will know that bits BIT_A,..., BIT_I,... will **only**
* be set in the mask of (BIT_A | BIT_B | ... | BIT_Z) */
}
as with a & (BIT_A | BIT_B | ... ) you force all bits not in the set to be zero, so only the bits in the set will conserve their values. With the second mask, you generate a bitmap with only the bits of the set you want to be set (and of course the bits that are not in the set forced zero) so if you compare both values for equalness, you'll get the expected result.
NOTE
As an answer to your question, the particular case in which you want all the bits equal to one, is to make both masks equal. For your case, you want to check if both bits are zero, then your test is (the second mask has no bits set, so it is zero):
if (a & ((1 << 3) | (1 << 5)) == 0) { ...
(All bits in the second mask are zero as the required mask, and both, the third and the fifth bits are set in the first mask) This can be written in a more compact form as (you can see it written as):
if (!(a & 0x28)) { /* 0x28 is the octal for 00101000, with the bits you require */
WHY THE CODE YOU WROTE IS NOT CORRECT
First you mix logical operators like ! with bitmasks, making !(1<<3)to eval to 0 (1<<3 is different of 0 so it is true, negating gives 0) and the same for the !(1<<5) subexpression. When you mask a with those values makes you get a & 0 ==> 0 and a & 0 ==> 0 and anding both together gives 0 && 0 ==> 0. So the result value of your expression is 0 -- false always, independent of the original value of a.

how to find specific instruction using bit field? (bit comparison)

I want to find type of instruction(16-bit).
For example Type 0 instruction, it always has its leftmost two bit is 0.
0 0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? (16-bit bit field; ? is don't care)
I want to find this type 0 instruction using only leftmost two bit.
What should I do? (C language)
Ultimately, I wanna find that an instruction(such as 0012345678910111 or 0098765432123456) is type 0 instruction.
Sorry for my english T_T.
I want some code like below (in Java)
if (instruction.containsBit(type0) == true)
You use the & (bitwise AND) to mask out the relevant bits, then == to do the comparison:
uint16_t opcode = 0xf001;
if((opcode & 0xc000) == 0)
{
printf("opcode 0x%0x has topmost two bits cleared", opcode);
}
The 0xc000 constant, typically called "the mask" in code like this, is 1100 0000 0000 0000 in binary, so when applied with the bitwise AND, it will result in a number having 1s where both arguments have 1s. Comparing the result to 0 makes sure the opcode does not have any 1s in locations where the mask has 1s.
The operator & in C can perform an simple AND operation. See also here.
Then you just need the bitmask of the bits you want to check on the right-side of this operator.
#include <stdio.h>
int main (int argc, char **argv){
unsigned short a = 0x7FFF;
unsigned short b = 0x80FF;
if( a & 0x8000 ) printf("a Highest bit set\n");
if( a & 0x4000 ) printf("a Second highest bit set\n");
if( b & 0x8000 ) printf("b Highest bit set\n");
if( b & 0x4000 ) printf("b Second highest bit set\n");
return 0;
}
#define true ((uint8_t)1)
#define false ((uint8_t)0)
uint8_t IsThisInstructionType0(uint16_t instruction)
{
uint16_t andMask = 0x8000;
if(((instruction & andMAsk) >> 15) == 0)
{
andMask >>= 1;
if( ( ((instruction & andMAsk) << 1) >> 15 ) == 0)
return true;
}
else return false;
}
Something like this:
int GetInstructionClass (uint16_t ins)
{
return (ins>>14)&3;
}
This expression: (ins>>14)&3 works like this:
First, ins has this format:
C C X X X X X X X X X X X X X X
Where C are the bits that form the instruction class. X means "don't care for now".
The first operation, >>14 shifts the number to the right so it ends like this:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 C C
Note that as we are using an uint16_t, the shift operation should enter 0's from the left, but as the function result is int, and int is signed, I'm not sure if the type promotion happens before of after the shifting is performed. I'd say that the type promotion happens after the evaluation of the whole expression.
Anyway, and just to be sure that no unwanted bits will be returned, we will mask the result of the shifting so that only bits 0 and 1 are preserved. The mask is:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 which is 3.
So the final result will be a number with bits 0 and 1 being the same as bits 14 and 15 of the original ins argument, giving 0, 1, 2 or 3 (I repeat: I'm assuming that the whole expression is being treated as a 16 bit number). This works with MinGW, Visual C++ and GCC in a 32-bit environment.

How do I check if an integer is even or odd using bitwise operators

How do I check if an integer is even or odd using bitwise operators
Consider what being "even" and "odd" means in "bit" terms. Since binary integer data is stored with bits indicating multiples of 2, the lowest-order bit will correspond to 20, which is of course 1, while all of the other bits will correspond to multiples of 2 (21 = 2, 22 = 4, etc.). Gratuituous ASCII art:
NNNNNNNN
||||||||
|||||||+−− bit 0, value = 1 (20)
||||||+−−− bit 1, value = 2 (21)
|||||+−−−− bit 2, value = 4 (22)
||||+−−−−− bit 3, value = 8 (23)
|||+−−−−−− bit 4, value = 16 (24)
||+−−−−−−− bit 5, value = 32 (25)
|+−−−−−−−− bit 6, value = 64 (26)
+−−−−−−−−− bit 7 (highest order bit), value = 128 (27) for unsigned numbers,
value = -128 (-27) for signed numbers (2's complement)
I've only shown 8 bits there, but you get the idea.
So you can tell whether an integer is even or odd by looking only at the lowest-order bit: If it's set, the number is odd. If not, it's even. You don't care about the other bits because they all denote multiples of 2, and so they can't make the value odd.
The way you look at that bit is by using the AND operator of your language. In C and many other languages syntactically derived from B (yes, B), that operator is &. In BASICs, it's usually And. You take your integer, AND it with 1 (which is a number with only the lowest-order bit set), and if the result is not equal to 0, the bit was set.
I'm intentionally not actually giving the code here, not only because I don't know what language you're using, but because you marked the question "homework." :-)
In C (and most C-like languages)
if (number & 1) {
// It's odd
}
if (number & 1)
number is odd
else // (number & 1) == 0
number is even
For example, let's take integer 25, which is odd.
In binary 25 is 00011001. Notice that the least significant bit b0 is 1.
00011001
00000001 (00000001 is 1 in binary)
&
--------
00000001
Just a footnote to Jim's answer.
In C#, unlike C, bitwise AND returns the resulting number, so you'd want to write:
if ((number & 1) == 1) {
// It's odd
}
if(x & 1) // '&' is a bit-wise AND operator
printf("%d is ODD\n", x);
else
printf("%d is EVEN\n", x);
Examples:
For 9:
9 -> 1 0 0 1
1 -> & 0 0 0 1
-------------------
result-> 0 0 0 1
So 9 AND 1 gives us 1, as the right most bit of every odd number is 1.
For 14:
14 -> 1 1 1 0
1 -> & 0 0 0 1
------------------
result-> 0 0 0 0
So 14 AND 1 gives us 0, as the right most bit of every even number is 0.
Also in Java you will have to use if((number&1)==1){//then odd}, because in Java and C# like languages the int is not casted to boolean. You'll have to use the relational operators to return
a boolean value i.e true and false unlike C and C++ like languages which treats non-zero value as true.
You can do it simply using bitwise AND & operator.
if(num & 1)
{
//I am odd number.
}
Read more over here - Checking even odd using bitwise operator in C
Check Number is Even or Odd using XOR Operator
Number = 11
1011 - 11 in Binary Format
^ 0001 - 1 in Binary Format
----
1010 - 10 in Binary Format
Number = 14
1110 - 14 in Binary Format
^ 0001 - 1 in Binary Format
----
1111 - 15 in Binary Format
AS It can observe XOR Of a number with 1, increments it by 1 if it is
even, decrements it by 1 if it is odd.
Code:
if((n^1) == (n+1))
cout<<"even\n";
else
cout<<"odd\n";
#include <iostream>
#include <algorithm>
#include <vector>
void BitConvert(int num, std::vector<int> &array){
while (num > 0){
array.push_back(num % 2);
num = num / 2;
}
}
void CheckEven(int num){
std::vector<int> array;
BitConvert(num, array);
if (array[0] == 0)
std::cout << "Number is even";
else
std::cout << "Number is odd";
}
int main(){
int num;
std::cout << "Enter a number:";
std::cin >> num;
CheckEven(num);
std::cout << std::endl;
return 0;
}
In Java,
if((num & 1)==0){
//its an even num
}
//otherwise its an odd num
This is an old question, however the other answers have left this out.
In addition to using num & 1, you can also use num | 1 > num.
This works because if a number is odd, the resulting value will be the same since the original value num will have started with the ones bit set, however if the original value num was even, the ones bit won't have been set, so changing it to a 1 will make the new value greater by one.
Approach 1: Short and no need for explicit comparison with 1
if (number & 1) {
// number is odd
}
else {
// number is even
}
Approach 2: Needs an extra bracket and explicit comparison with 0
if((num & 1) == 0){ // Note: Bracket is MUST around num & 1
// number is even
}
else {
// number is odd
}
What would happen if I miss the bracket in the above code
if(num & 1 == 0) { } // wrong way of checking even or not!!
becomes
if(num & (1 == 0)) { } // == is higher precedence than &
https://en.cppreference.com/w/cpp/language/operator_precedence

Resources