Hello the function is called allOddBits with one input so if the function identifies 1 when the odd numbered bits are then it will return 1 otherwise it return 0;
Thank you for the help in advance.
We are only allowed to use these ! ~ & ^ | + << >> bit operation not more than 12 times. This way is always returning a 1 which is not correct because when the value of 'a' doesn't have odd numbered bits equal to 1, it should not return 1.
int main(int argc, char *argv[]) {
unsigned a,c;
a= 0xAAAAAAAA; // given bits, it can be anything
c= a>>31; // Shifting 31 bits to the right and fill in 0 instead
c= ~c; // flipping the bits so it can all be 1 except for LSB
printf(": %u\n", !!c);
}
Never mind guys,.. I figured out the solution but it did take some time. I appreciate your input though.
unsigned int x = strtoul(argv[1], NULL, 10);
unsigned int a = 0x55555555; // or 0xAAAAAAAA if you count LSB as bit 0
return ((x & a) == a);
Related
I want to apply a bitmask to a number that will mimic the absolute value function for 2's complement encoded signed 32 bit integers. So far, I have
int absoluteValue(int x) {
int sign = x >> 31; //get most significant byte...all 1's if x is < 0, all 0's if x >= 0
int negated = (~x + 1) & sign; //negates the number if negative, sets to 0 if positive
//what should go here???
}
Am I going in the right direction? I'm not really sure where to go from here (mostly just how to apply a mask to keep the original positive value). I also don't want to use any conditional statements
Bizarre question. What about
return (negated << 1) + x;
So put together this makes:
int absoluteValue(int x) {
int sign = x >> 31; //get most significant byte...all 1's if x is < 0, all 0's if x >= 0
int negated = (~x + 1) & sign; //negates the number if negative, sets to 0 if positive
return (negated << 1) + x;
}
The last part
negated = (~x + 1) & sign;
is wrong, you are going to get either 1 or 0, you have to create a mask with all
first 31 bits to 0 and only the last one to either 0 or 1.
Assuming that for you target you are dealing with 32 bit integers with 2
complement, you can do this:
#include <stdio.h>
// assuming 32bit, 2 complement
int sign_inverse(int n)
{
int mask = ~n & 0x80000000U;
if(n == 0)
mask = 0;
return (~n + 1) | mask;
}
int main(void)
{
int a = 5;
int b = -4;
int c = 54;
int d = 0;
printf("sign_inverse(%d) = %d\n", a, sign_inverse(a));
printf("sign_inverse(%d) = %d\n", b, sign_inverse(b));
printf("sign_inverse(%d) = %d\n", c, sign_inverse(c));
printf("sign_inverse(%d) = %d\n", d, sign_inverse(d));
return 0;
}
but you need at least 1 if for the case of 0, because the mask for 0 is 0x80000000.
The output of this is:
$ ./b
sign_inverse(5) = -5
sign_inverse(-4) = 4
sign_inverse(54) = -54
sign_inverse(0) = 0
Please note that two's complement representation is not guaranteed, and also the behaviour of operator >> on signed values, where the result get's "filled" with 1-bits is implementation defined (cf., for example, cppreference.com/arithmetic operations):
For negative LHS, the value of LHS >> RHS is implementation-defined
where in most implementations, this performs arithmetic right shift
(so that the result remains negative). Thus in most implementations,
right shifting a signed LHS fills the new higher-order bits with the
original sign bit (i.e. with 0 if it was non-negative and 1 if it was
negative).
But if you take this for given, and if you just want to use bit wise operations and operator +, you are already going into the right direction.
The only thing is that you should take into account the mask you create ( i.e. your sign) in that you toggle the bits of x only in the case where x is negative. You can achieve this by the XOR-operator as follows:
int x = -3000;
unsigned int mask = x >> 31;
int sign = mask & 0x01;
int positive = (x^mask) + sign;
printf("x:%d mask:%0X sign:%d positive:%d\n",x,mask,sign,positive);
I want to extract a particular range of bits in an integer variable.
For example: 0xA5 (10100101)
I want to extract from bit2 to bit5. i.e 1001 to a variable and count number of zeros between them.
I have another variable which give the starting point, which means in this case the value of the variable is 2. So the starting point can be find by 0xA5 >> 2.
5th bit position is a random position here..means it can be 6 or 7. The main idea is whichever bit is set to 1 after 2nd bit. I have to extract that..
How can I do rest of the part ?
Assuming you are dealing with unsigned int for your variable.
You will have to construct the appropriate mask.
Suppose you want the bits from position x to position y, there need to be y - x + 1 1s in the mask.
You can get this by -
int digits = y - x + 1;
unsigned int mask = 1u << digits - 1;
Now you need to remove the lower x bits from the initial number, which be done by -
unsigned int result = number >> x;
Finally apply the mask to remove the upper bits -
result = result & mask;
In this example we put 0 or 1 values into array. After that you can treat array as you like.
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) {
uint8_t value = 0xA5;
unsigned char bytes[8];
unsigned char i;
for (i = 0; i < 8; i++) {
bytes[i] = (value & (1 << i)) != 0 ? 1 : 0;
}
for (i = 0; i < 8; i++) {
printf("%d", bytes[i]);
}
return 0;
}
You could use a mask and the "&" (AND) operation:
a = 0xA5;
a = a >> OFFSET; //OFFSET
mask = 0x0F; // equals 00001111
a = a & mask;
In your example a = 0xA5 (10100101), and the offset is 2.
a >> 2 a now equals to 0x29 (00101001)
a & 0x0F (00101001 AND
00001111) = 00001001 = 0x09
If you want bits from the offset X then shift right by X.
If you want Y bits, then then mask (after the shift) will be 2 to the power of Y minus one (for your example with four bits, 2 to the power of 4 is 16, minus one is 15 which is 1111 binary). This can be dome by using left-shifting by Y bits and subtracting 1.
However, the masking isn't needed if you want to count the number of zeros in the wanted bits, only the right shift. Loop Y times, each time shifting a 1 left one step, and check using bitwise and if the value is zero. If it is then increment a counter. At the end of the loop the counter is the number of zeros.
To put it all in code:
// Count the number of zeros in a specific amount of bits starting at a specific offset
// value is the original value
// offset is the offset in bits
// bits is the number of bits to check
unsigned int count_zeros(unsigned int value, unsigned int offset, unsigned int bits)
{
// Get the bits we're interested in the rightmost position
value >>= offset;
unsigned int counter = 0; // Zero-counter
for (unsigned int i = 0; i < bits; ++i)
{
if ((value & (1 << i)) == 0)
{
++counter; // Bit is a zero
}
}
return counter;
}
To use with the example data you have:
count_zeros(0xa5, 2, 4);
The result should be 2. Which it is if you see this live program.
int32_t do_test(int32_t value, int32_t offset)
{
int32_t _zeros = 1;
value >>= offset;
int i = 1;
while(1) {
if((value >> i) % 2 == 0) {
_zeros += 1;
i++;
} else {
break;
}
}
}
int result = (0xA5 >> 2) & 0x0F;
Truth table for the & operator
| INPUTS | OUTPUT |
-----------------------
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
-----------------------
I have a byte array represented as
char * bytes = getbytes(object); //some api function
I want to check whether the bit at some position x is set.
I've been trying this
int mask = 1 << x % 8;
y= bytes[x>>3] & mask;
However y returns as all zeros? What am I doing incorrectly and is there an easier way to check if a bit is set?
EDIT:
I did run this as well. It didn't return with the expected result either.
int k = x >> 3;
int mask = x % 8;
unsigned char byte = bytes[k];
return (byte & mask);
it failed an assert true ctest I ran. Byte and Mask at this time where "0002" and 2 respectively when printed from gdb.
edit 2: This is how I set the bits in the first place. I'm just trying to write a test to verify they are set.
unsigned long x = somehash(void* a);
unsigned int mask = 1 << (x % 8);
unsigned int location = x >> 3;
char* filter = getData(ref);
filter[location] |= mask;
This would be one (crude perhaps) way from the top of my head:
#include "stdio.h"
#include "stdlib.h"
// this function *changes* the byte array
int getBit(char *b, int bit)
{
int bitToCheck = bit % 8;
b = b + (bitToCheck ? (bit / 8) : (bit / 8 - 1));
if (bitToCheck)
*b = (*b) >> (8 - bitToCheck);
return (*b) & 1;
}
int main(void)
{
char *bytes = calloc(2, 1);
*(bytes + 1)= 5; // writing to the appropiate bits
printf("%d\n", getBit(bytes, 16)); // checking the 16th bit from the left
return 0;
}
Assumptions:
A byte is represented as:
----------------------------------------
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 |... |
----------------------------------------
The left most bit is considered bit number 1 and the right most bit is considered the max. numbered bit (16th bit in a 2 byte object).
It's OK to overwrite the actual byte object (if this is not wanted, use memcpy).
I'm stuck understanding bit operations on integers in C.
Suppose I have the number 13. Its binary representation is 1101. How can I set the bit at its second position? How can I clear the bit?
Here is the function I wrote so far for setting the bit:
int setBit(int data, int pos, int val)
{
if (val==1)
data |= (1U << (pos - 1));
else
data ^= (1U << (pos-1));
return data;
}
Will this work correctly?
n = n & (~(1U <<x)) will reset the bit in position x.
Actually what we are doing suppose n=1101
We want to reset 3rd bit.
How does it work?
So 1U <<3=000....1000
~( 1U <<3)=111....0111
n=000..1101
& 111..0111
Result is 000..0101.
For inserting a bit y at position x:(position starts from 0)
1101---->11y01
Giving the example for position 2.
num= FFFF FFFF (in hex)(all 1's) //1111......1111
number=N // in which you will insert bit
num1=num<<x; //for x=2 as in this case
//num1=1111.....1100
num2=~(num1); //num2=0000.....0011
lowbits=N & num2; // =0000.....0001 (N=1101)
highbits= N &num1;// =0000.....1100
highbits<<=1; // =0000....11000
N= highbits | lowbits;//=0000....11001
Now set the x-th bit(here x=2) as you required using the method described below
Note: More generally changing the kth bit of number n to y (maybe 0 or 1) can be done this way
n^=(-y ^ n) & (1U <<k); (&- logical and)
Deletion of a bit is similar to insertion. Step by step perform the operation and you will get it.
EDIT: I have changed the use of 1 to 1U because in first case when using only 1 without any modifiers is defined to be an signed int. From K&R the right shifts of signed values are implementation defined. Also if you left-shift a signed number so that the sign bit is affected, the result is undefined.
These operations on unsigned value have well define behaviour: Vacated fields are filled with zeroes.
Setting, clearing and toggling the state of a bit is straightforward:
inline void bit_set (unsigned long *bf, unsigned char n)
{ *bf |= (1 << n); }
inline void bit_clear (unsigned long *bf, unsigned char n)
{ *bf &= ~(1 << n); }
inline void bit_toggle (unsigned long *bf, unsigned char n)
{ *bf ^= (1 << n); }
Note: bitfields, and the functions above, are zero based (i.e. the least significant bit is bit 0 not bit 1) So if you want to clear, set or toggle the second bit from the right (bit index 1, the 2's bit (binary), or bit 2 counting right-to-left), you pass a bit index of 1. n in the functions above is the bit index. The following is a quick reference:
+-----+-----+-----+-----+-----+-----+-----+-----+
bit index | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-----+-----+-----+-----+-----+-----+-----+-----+
binary | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
+-----+-----+-----+-----+-----+-----+-----+-----+
Here is a quick example of the use operating on bit 1, (the 2's bit in binary):
#include <stdio.h>
#include <stdlib.h>
#define WDSZ 64
/* bit functions */
inline void bit_set (unsigned long *bf, unsigned char n) { *bf |= (1 << n); }
inline void bit_clear (unsigned long *bf, unsigned char n) { *bf &= ~(1 << n); }
inline void bit_toggle (unsigned long *bf, unsigned char n) { *bf ^= (1 << n); }
/* simple return of binary string */
char *binstr (unsigned long n);
int main (int argc, char **argv) {
unsigned long bf = (argc > 1) ? strtoul (argv[1], NULL, 10) : 13;
printf ("\n original value : %3lu (%s)\n", bf, binstr (bf));
bit_set (&bf, 1);
printf (" set bit 1 : %3lu (%s)\n", bf, binstr (bf));
bit_clear (&bf, 1);
printf (" clear bit 1 : %3lu (%s)\n", bf, binstr (bf));
bit_toggle (&bf, 1);
printf (" toggle bit 1 : %3lu (%s)\n\n", bf, binstr (bf));
return 0;
}
/* simple return of binary string */
char *binstr (unsigned long n) {
static char s[WDSZ + 1] = {0};
char *p = s + WDSZ;
while (n) {
p--;
*p = (n & 1) ? '1' : '0';
n >>= 1;
}
return p;
}
Output
$ ./bin/bitsetcleartoggle
original value : 13 (1101)
set bit 1 : 15 (1111)
clear bit 1 : 13 (1101)
toggle bit 1 : 15 (1111)
Here is a simple answer for what I understand your problem to be:
int setBit(int data, int pos, int val) {
if (val)
return data | (1U << (pos - 1));
else
return data & ~(1U << (pos - 1));
}
But I think numbering the bits starting at 1 is not a good idea. The more common usage is to number the bits from 0 to sizeof(type) * CHAR_BIT - 1
whenever I have a problem like this I will break it down into smaller parts...
suppose i have no 13 binary of 13 is 1101
now how can i add extra bit at second position?
ok that is pretty straight forward... first let make a number with a bit in the second position, zero's everywhere else... we will use an int for convenience...
int mask = 2; // or 0x2 if you rather or 0b10 if your compiler supports that ...
well that isn't very special, I can't reuse that machinery as it were... so let try a different way...
int mask = 1 << 1; // 1 in the fist position moved one to the left...
ok now we have part, now there are 2 intuitive ways to set that on our 13...
int answer = 13 | mask; // binary OR
or
int answer = 13 + mask;
these 2 are the same for 13... but will give you different answers for 14... because + always adds the value, and | will only change the bits that aren't set on the left side... so you need to pick the semantics that are correct for you...
now your second question is a little trickier ... first we will pick the same mask...
//pick nth bit
int mask = 1 < n;
// now to toggle that on a number... XOR
int answer = q ^ mask;
I like using the n'th vs position because it makes more sense in the 0 case...
//For Inserting Bit
int insertbit(int data,int pos,int val)
{
int no1,no2;
no1=data;
no1=no1>>(pos-1);
no1=no1<<(pos-1);
no2=data-no1;
no1=no1<<1;
no1=no1 | no2;
if(val==1)
{
no1=setbit(no1,pos,val);
}
return no1;
}
//Setting Bits
int setbit(int data,int pos,int val)
{
int no=1;
no=no<<(pos-1);
if(val==0)
{
no=~no;
data=data&no;
}
else
{
data=no|data;
}
return data;
}
I Coded This Way But I Need Some Shortcut for code insert function
I wan't to set the last n bits of any given number to 1. I have a number (which is variable in it's lenght) and a variable n.
Example:
12 (dec) set last 2 bits
Output: 15
Now the basic operation should be something like:
return 0b11 | 12;
But how can I make 0b11 variable in length?
Thank you!
Try this:
int SetLastBits(int value,int numOfBits)
{
return value | ((1<<numOfBits)-1);
}
You can set the last n bits of a number to 1 in the following manner:
int num = 5; // number of bits to set to 1
int val = <some_value>;
val |= (1 << num) - 1;
You can do it like this:
uint32_t set_last_n_bits(uint32_t x, uint32_t bits)
{
return x | ((1U << bits) - 1U);
}
This is also a relatively rare case where a macro might be justifiable, on the grounds that it would work with different integer types.
As all others have showed the same approach I will show one more approach
int value;
//...
value |= ~( ~0u << n );
Here is a demonstrative program
#include <stdio.h>
int set_bits( int x, size_t n )
{
return x | ~( ~0u << n );
}
int main(void)
{
int x = 12;
printf( "%d\t%d\n", x, set_bits( x, 2 ) );
return 0;
}
The output is
12 15