What does this bit-manipulating function do? - c

unsigned long ccNextPOT(unsigned long x){
x = x - 1;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
return x + 1;
}

The OR and SHIFT statements fills with ones all bits of x to the right of most significant bit (up to 32 bits). Together with the pre-decrement and post-increment statements, this computes (as the function name suggets) the next power-of-two number, equal or greater than the given number (if x is greater than 0 and less than 2^32)

Related

C Bitwise Circle Shifting - Unexpected Results

I'm currently working through the K&R C book exercises and am on exercise 8 of chapter 2. The challenge is to write a function 'rotright' that rotates (or circle shifts) the bits of unsigned integer x by n bits. I believe I've come up with a solution, but it's not returning what I would expect. Given the number 213, which is 11010101 in binary, rotating 2 bits to the right would yield 01110101, which is 117. However, my program upon being given x=213 and n=2 returns 53. I've tried writing out the process of what's happening to the integer in binary form in comments and can't find a problem. Any help would be appreciated.
#include <stdio.h>
unsigned rotright(unsigned x, int n)
{
/* Example with x = 11010101 (213 in decimal), n = 2
First iteration:
x = (01101010) | ~(11111111 >> 1) = 11101010
Second iteration:
x = (01110101) | ~(11111111 >> 0) = 01110101
Returns 01110101
right shifts only if last bit of x == 1, then sets first bit of right shifted x to 1
if last bit of x == 0, x is right shifted by 1 and then unchanged.
(01101010) | ~(11111111 >> (11010101 & 00000001))
= 01101010 | ~(11111111 >> 00000001)
= 01101010 | 10000000 = 11101010
(11101010) | ~(11111111 >> (11101010 & 00000001))
= 01110101 | ~(11111111 >> 0)
= 01110101 | 00000000 = 01110101
*/
for (; n > 0; n--)
x = (x >> 1) | ~(~0 >> (x & 1));
return x;
}
int main()
{
printf("%d\n", rotright(213, 2));
return 0;
}
x = (x >> 1) | ~(~0 >> (x & 1));
you get 53 because this is (213 >> 2)
~(~0 >> (x & 1)) is always 0, because ~0 is -1, and (-1 >> n) is again -1 in your case, and finally ~(-1) is 0
You want that :
#include <stdio.h>
#include <limits.h>
unsigned rotright(unsigned x, int n)
{
unsigned mask = (1u << (CHAR_BIT * sizeof(int) - 1));
for (; n > 0; n--) {
x = (x / 2) | ((x & 1) ? mask : 0);
}
return x;
}
int main()
{
printf("%d\n", rotright(213, 2));
return 0;
}
On 32bits the result is 1073741877 being 1000000000000000000000000110101, not 117 whose supposes you work on 8 bits

Check if a number can be represented using n bits in 2’s complement

I'm working on a function that returns 1 when x can be represented as an n-bit, 2’s complement number and 0 if it can't. Right now my code works for some examples like (5, 3), (-4, 3). But I can't get it to work for instances where n is bigger than x like (2, 6). Any suggestions as to why?
I do have restrictions though which include casting, either explicit or implicit, relative comparison operators (<, >, <=, and >=), division, modulus, and multiplication, subtraction, conditionals (if or ? :), loops, switch statements, function calls, and macro invocations. Assume 1 < n < 32.
int problem2(int x, int n){
int temp = x;
uint32_t mask;
int maskco;
mask = 0xFFFFFFFF << n;
maskco = (mask | temp);
return (maskco) == x;
}
In your function, temp is just redundant, and maskco always have the top bit(s) set, so it won't work if x is a positive number where the top bit isn't set
The simple solution is to mask out the most significant bits of the absolute value, leaving only the low n bits and check if it's still equal to the original value. The absolute value can be calculated using this method
int fit_in_n_bits(int x, int n)
{
int maskabs = x >> (sizeof(int) * CHAR_BIT - 1);
int xabs = (x + maskabs) ^ maskabs; // xabs = |x|
int nm = ~n + 1U; // nm = -n
int mask = 0xFFFFFFFFU >> (32 + nm);
return (xabs & mask) == xabs;
}
Another way:
int fit_in_n_bits2(int x, int n)
{
int nm = ~n + 1U;
int shift = 32U + nm;
int masksign = x >> (shift + 1);
int maskzero = 0xFFFFFFFFU >> shift;
return ((x & maskzero) | masksign) == x;
}
You can also check out oon's way here
int check_bits_fit_in_2s_complement(signed int x, unsigned int n) {
int mask = x >> 31;
return !(((~x & mask) + (x & ~mask))>> (n + ~0));
}
One more way
/*
* fitsBits - return 1 if x can be represented as an
* n-bit, two's complement integer.
* 1 <= n <= 32
* Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 2
*/
int fitsBits(int x, int n) {
int r, c;
c = 33 + ~n;
r = !(((x << c)>>c)^x);
return r;
}
Related:
How to tell if a 32 bit int can fit in a 16 bit short
counting the number of bit required to represent an integer in 2's complement
int problem2_mj(int x, int n){
unsigned int r;
int const mask = (-x) >> sizeof(int) * CHAR_BIT - 1;
r = (-x + mask - (1 & mask)) ^ mask; // Converts +n -> n, -n -> (n-1)
return !(((1 << (n-1)) - r) >> sizeof(int) * CHAR_BIT - 1);
}
Find the absolute value and subtract 1 if the number was negative
Check if number is less than or equal to 2n-1
Check a working demo here
As per your updated request here is the code how to add two numbers:
int AddNums(int x, int y)
{
int carry;
// Iteration 1
carry = x & y;
x = x ^ y;
y = carry << 1;
// Iteration 2
carry = x & y;
x = x ^ y;
y = carry << 1;
...
// Iteration 31 (I am assuming the size of int is 32 bits)
carry = x & y;
x = x ^ y;
y = carry << 1;
return x;
}

Efficient computation of a power of 2

I have a requirement to compute k as the smallest power of 2 which is >= an integer value, n (n is always > 0)
currently I am using:
#define log2(x) log(x)/log(2)
#define round(x) (int)(x+0.5)
k = round(pow(2,(ceil(log2(n)))));
this is in a performance critical function
Is there a more computationally efficient way of calculating k?
/* returns greatest power of 2 less than or equal to x, branch-free */
/* Source: Hacker's Delight, First Edition. */
int
flp2(int x)
{
x = x | (x>>1);
x = x | (x>>2);
x = x | (x>>4);
x = x | (x>>8);
x = x | (x>>16);
return x - (x>>1);
}
It's entertaining to study it and see how it works. I think the only way for you to know for sure which of the solutions you see will be optimal for your situation is to use all of them in a text fixture and profile it and see which is most efficient for your purpose.
Being branch-free, this one is likely to be quite good performance-wise relative to some others, but you should test it directly to be sure.
If you want the least power of two greater than or equal to X, you can use a slightly different solution:
unsigned
clp2(unsigned x)
{
x = x -1;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
return x + 1;
}
int calculate_least_covering_power_of_two(int x)
{
int k = 1;
while( k < x ) k = k << 1;
return k;
}
lim = 123;
n = 1;
while( ( n = n << 1 ) <= lim );
Multiply your number by 2 until it's bigger than lim.
Left shift of one multiplies value by 2.
Yes, You can calculate this by simply taking the number in question, and using bit-shifts to determine the power of 2.
Right-shifting takes all the bits in the number and moves them to the right, dropping the far right (least significant) digit. It is equivalent to performing an integer division by 2. Left-shifting a value moves all the bits to the left, dropping the bits that shift off the left end, and adding zeroes to the right end, effectively multiplying the value by 2.
So if you count how many times you need to right shift before the number reaches zero, you have calculated the integer portion of the base 2 logarithm. Then use it to create your result by left-shifting the value 1 that many times.
int CalculateK(int val)
{
int cnt = 0;
while(val > 0)
{
cnt++;
val = val >> 1;
}
return 1 << cnt;
}
EDIT: Alternatively, and a bit simpler: you don't have to calculate the count
int CalculateK(int val)
{
int res = 1;
while(res <= val) res <<= 1;
return res ;
}
k = 1 << (int)(ceil(log2(n)));
You can take advantage of the fact that binary digits represent powers of two (1 is 1, 10 is 2, 100 is 4, etc). Shifting 1 left by the exponent of 2 gives you the same value, but it's much faster.
Although if you can somehow avoid the ceil(log2(n)) you will see a much larger performance increase.
Source: hackersdelight.org
/* altered to: power of 2 which is greater than an integer value */
unsigned clp2(unsigned x) {
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
return x + 1;
}
Keep in mind you will need to add:
x = x | (x >> 32);
For 64bit numbers.

Is it possible to rewrite modulo (2^n - 1) using bitwise and restricted operators

For unsigned int x, is it possible to calculate x % 255 (or 2^n - 1 in general) using only the following operators (plus no loop, branch or function call)?
!, ~, &, ^, |, +, <<, >>.
Yes, it's possible. For 255, it can be done as follows:
unsigned int x = 4023156861;
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
x = (x & 255) + (x >> 8);
// At this point, x will be in the range: 0 <= x < 256.
// If the answer 0, x could potentially be 255 which is not fully reduced.
// Here's an ugly way of implementing: if (x == 255) x -= 255;
// (See comments for a simpler version by Paul R.)
unsigned int t = (x + 1) >> 8;
t = !t + 0xffffffff;
t &= 255;
x += ~t + 1;
// x = 186
This will work if unsigned int is a 32-bit integer.
EDIT: The pattern should be obvious enough to see how this can be generalized to 2^n - 1. You just have to figure out how many iterations are needed. For n = 8 and a 32-bit integer, 4 iterations should be enough.
EDIT 2:
Here's a slightly more optimized version combined with Paul R.'s conditional subtract code:
unsigned int x = 4023156861;
x = (x & 65535) + (x >> 16); // Reduce to 17 bits
x = (x & 255) + (x >> 8); // Reduce to 9 bits
x = (x & 255) + (x >> 8); // Reduce to 8 bits
x = (x + ((x + 1) >> 8)) & 255; // Reduce to < 255
Just create an array with all the values (only either need 32 or 64 entries (i.e. 128 or 512 bytes). Then just do a look up.
Sure. Just get out one of your old computer architecture textbooks and refresh your memory on boolean algebra. A CPU's ALU does it with ANDs and ORs; you can, too.
But why?
An academic exercise? Homework? Curiousity?

Using bitwise operators, find a logical not equivalent

Using only:
<< >> | ^ & +
How can I make a function that is equivalent to the logical not operator (!)?
Right now I have:
int i = (~x + 1) >> 31;
int j = (x + 1) >> 31;
i = i | j;
i = i & 1;
return i ^ 1;
It works for everything, but -1.
I will assume that you are working with ints that are 32-bit, signed, and use 2's complement notation. The unique thing about the number 0 is that neither 0 nor its negation have a 1 for the sign bits. This code would work if you were allowed to use the negation operator (-):
int not(int x)
{
return (-x | x) >> 31 & 1 ^ 1;
}
You can't use minus, but that is ok because for all x we know that -x is equal to ~x + 1 which is equal to (x ^ -1) + 1. That's how 2's complement notation works. So the final answer is:
int not(int x)
{
return ( (x^-1)+1 | x ) >> 31 & 1 ^ 1;
}
EDIT 1:
Ok, here is the "ANSI" version of the function that makes no assumption about the size of the int and does not rely on the undefined behavior of right-shifting a signed int. It works for me in MinGW:
int not(int x)
{
unsigned int y = x;
return (( ((y^-1)+1) | y ) >> (sizeof(x)*8-1)) ^ 1;
}
Assuming that x is a 32-bit unsigned value:
x = x | (x >> 1)
x = x | (x >> 2)
x = x | (x >> 4)
x = x | (x >> 8)
x = x | (x >> 16)
At this point, if x was 0 then it's still 0. If it had a non-zero value, it now has the bit pattern 111....111.
With a two-complement representation, you can now simply add 1 and get the desired result:
x = x + 1
This solution assumes quite a bit about integer representation, types, etc.
(The "code" above is not valid C code, of course).
Kind of 'cheating', but:
bool logicalNot(int i)
{
return((bool)i ^ true);
}
I'm assuming there's nothing in the rules about composition of functions/typecasting/implicit type conversions?

Resources