Fill with variable number of ones - c

What's the best way to fill a variable with an unknown (at compile time) number of ones? For example, let's say:
int n = 5;
int b = fillwithones(5);
now b contains 11111 (in binary).
I can't just hard code int b = 31 because n is not known ahead of time (in my application).
I could do something like this:
int b = pow(2, n) - 1
But using a pow seems very wasteful.
Thanks!

You can use left shift and then subtract 1:
unsigned int b = (1U << n) - 1U;
// Broken down into steps
// 1 = 00000001b
// 1 << 5 = 00100000b
// (1 << 5) - 1 = 00011111b
The reason this works is 1 shifted left n times is the same as 2n, as each sole bit position represents a power of 2.

A funny way to get the highest bits as 1 and the lowest bits as zero is using this nice trick:
#include <limits.h>
...
int b = INT_MIN >> n;
This works because shift left operation on a negative number will mantain the sign of the operation, and since INT_MIN is 10000....0000 shifting it by n to the left will give you n bits to 1, but on the other side.

Related

How to swap n bits from 2 numbers?

So currently (I don't know if the width is relevant) I have 2 128bit integers that I want to swap shift bits as shift is a part of a structure:
unsigned char shift : 7;
So I get the relevant bits like this:
__uint128_t rawdata = ((*pfirst << shift) >> shift), rawdatasecond = ((*psecond << shift) >> shift);
And then I swap them like this:
*pfirst = *pfirst >> 127 - shift << 127 - shift | rawdatasecond;
*psecond = *psecond >> 127 - shift << 127 - shift | rawdata;
But I feel like I'm missing something - or am I (not sure how to test either)?
Note:
__uint128_t *pfirst, *psecond; //pointer to some integers
As I understand the task, you would like to swap bits 0, ..., n-1 for two integers. This can be done as follows:
static inline void swapbits(__uint128_t *a, __uint128_t *b, unsigned n)
{
if(n <= 8 * sizeof(*a))
{
__uint128_t mask = (n < 8 *sizeof(*a)) ? (((__uint128_t)1) << n) - 1 : ~(__uint128_t)0;
__uint128_t bits_a = *a & mask; // Get the bits from a
__uint128_t bits_b = *b & mask; // Get the bits from b
*a = (*a & ~mask) | bits_b; // Set bits in a
*b = (*b & ~mask) | bits_a; // Set bits in b
}
}
Testing is a matter of calling the function with different combinations of values for a, b and n and checking that the result is as expected.
Clearly it is not feasible to test all combinations so a number of representative cases must be defined. It is not an exact science, but think about middle and corner cases: n=0, n=1, n=64, n=127, n=128 and a and b having different bit patterns around the left-most and right-most positions as well as around the n'th position.
static void SwapHighNBits(__uint128_t *a, __uint128_t *b, size_t n)
{
// Calculate number of uninvolved bits.
size_t NU = 128 - n;
// Calculate bitwise difference and remove uninvolved bits.
__uint128_t d = (*a ^ *b) >> NU << NU;
// Apply difference.
*a ^= d;
*b ^= d;
}
A good test suite would include all combinations of bits in the critical positions: The high bit, the lowest bit swapped, the highest bit not swapped, and the lowest bit. That is four bits in each of two operands, so eight bits total, 256 combinations for a specific value of n. Then test values of n from 2 to 126. Other bits can be filled randomly.
For n = 1, the high bit and the lowest bit swapped are identical, so make separate test code for that, or write the common test code carefully to cover that. Similarly, for n = 127, the highest bit not swapped and the lowest bit are identical, and, for n = 128, there are no bits not swapped.
If defined behavior is defined for n ≤ 0 or n > 128, add test cases for those. Note that the code above does not support n = 0, as NU will be 128, and the shifts are not defined by the C standard. Of course, for n = 0, one can simply return without making any changes.

left Rotate algorithm binary value in c

I'm trying to left rotate binary value:
int left_side=0;
for (int i = 0; i < n; i++)
{
left_side = left_side | ( ( number & ( 1<<BITS-i )) >> (BITS+i+1)-n );
}
BITS indicates the length of the binary value, n is the distance for rotation.
Example: 1000 , and n=1 which means the solution will be: 0001.
Some reason that I don't understand when I rotate it (from left to right side), lets take an example for number 253 which in binary sequence is 11111101 and n=3 (distance), the result from my code in binary sequence is 101 (which is 5).
Why the answer isn't 7? What I missed in my condition in this loop?
Thanks.
You want to rotate left your number n of a specific amount of bits.
Thus you have to shift your number to the left using n << amount and put the left bits to the right. This is done by putting the bits [0-amount[ to [NUMBER_BITS-amount,NUMBER_BITS[` using right shift.
For instance, if your number is an uint32_t you can use the following code (or easily adapt it to other types).
uint32_t RotateLeft(uint32_t n, int amount) {
return (n << amount)|(n >> (8*sizeof(uint32_t) - amount));
}
I think there are 2 approaches:
rotate by 1 bit n times
rotate by n % BITS bits only once
The rotation "wraps over" so we could just modulo every BITSth (8th) multiple of n to 0 in case someone would want to rotate 100 times. I think the second approach would be easier to understand, implement and read and why loop 100 times, if it can be done once?
Algorithm:
I will use 8 bits for demonstration, even though int is minimum 16 bits. The original MSB is marked by a dot.
.11110000 rl 2 == 110000.11
Well what has happened? 2 bits went right and the rest (BITS - 2) went left. That is just shift left and shift right "combined".
a = .11110000 << 2 == 110000.00
b = .11110000 >> (BITS - 2) == 000000.11
c = a | b
c == 110000.11
Easy, isn't it? Just remember to use n % BITS first and to use an unsigned type.
unsigned int rotateLeft(unsigned int number, int n) {
n %= BITS;
unsigned int left = number << n;
unsigned int right = number >> (BITS - n);
return left | right;
}

How to extract bits from a number in C?

I need to extract specific part (no of bits) of a short data type in C.
Fox example, i have a binary of 45 as 101101 and i just want 2 bits in middle such as (10)
I started with C code 2 days ago so don't given a lot of functions.
How do i extract them ?
Please search for bit-wise operations for more general information, and bit masking for your specific question. I wouldn't recommend to jump to bits if you are new to programming though.
The solution will slightly change depending on whether your input will be fixed in length. If it won't be fixed, you need to arrange you mask accordingly. Or you can use a different method, this is probably simplest way.
In order to get specific bits that you want, you can use bitmasking.
E.g you have 101101 and you want those middle two bits, if you & this with 001100, only bits that are 1 on the mask will remain unchanged in the source, all the other bits will be set to 0. Effectively, you will have those bits that you are interested in.
If you don't know what & (bitwise and) is, it takes two operands, and returns 1 only if first AND second operands are 1, returns 0 otherwise.
input : 1 0 1 1 0 1
mask : 0 0 1 1 0 0
result : 0 0 1 1 0 0
As C syntax, we can do this like:
unsigned int input = 45;
unsigned int mask = 0b001100; // I don't know if this is standard notation. May not work with all compilers
// or
unsigned int mask = 12; // This is equivalent
unsigned int result = input & mask; // result contains ...001100
As yo can see, we filtered the bits we wanted. The next step depends on what you want to do with those bytes.
At this point, the result 001100 corresponds to 12. I assume this is not really useful. What you can do is, you can move those bits around. In order to get rid of 0s at the right, we can shit it 2 bits to the right. For this, we need to use >> operator.
0 0 1 1 0 0 >> 2 ≡ 0 0 0 0 1 1
result = result >> 2; // result contains ...011
From there, you can set a bool variable to store each of them being 1 or 0.
unsigned char flag1 = result & 0b01; // or just 1
unsigned char flag2 = result & 0b10; // or just 2
You could do this without shifting at all but this way it's more clear.
You need to mask the bits that you want to extract. If suppose you want to create mask having first 4 bits set. Then you can do that by using:
(1 << 4) - 1
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void print_bin(short n)
{
unsigned long i = CHAR_BIT * sizeof(n);
while(i--)
putchar('0' + ((n >> i) & 1));
printf("\n");
}
int main()
{
short num = 45; /* Binary 101101 */
short mask = 4; /* 4 bits */
short start = 0; /* Start from leftmost bit
position 0 */
print_bin((num >> start) & ((1 << mask) - 1)); /* Prints 1101 */
mask = 2; /* 2 bits */
start = 1; /* start from bit indexed at position 1 */
print_bin((num >> start) & ((1 << mask) - 1)); /* Prints 10 */
return 0;
}
Output:
0000000000001101
0000000000000010

Moving a "nibble" to the left using C

I've been working on this puzzle for awhile. I'm trying to figure out how to rotate 4 bits in a number (x) around to the left (with wrapping) by n where 0 <= n <= 31.. The code will look like:
moveNib(int x, int n){
//... some code here
}
The trick is that I can only use these operators:
~ & ^ | + << >>
and of them only a combination of 25. I also can not use If statements, loops, function calls. And I may only use type int.
An example would be moveNib(0x87654321,1) = 0x76543218.
My attempt: I have figured out how to use a mask to store the the bits and all but I can't figure out how to move by an arbitrary number. Any help would be appreciated thank you!
How about:
uint32_t moveNib(uint32_t x, int n) { return x<<(n<<2) | x>>((8-n)<<2); }
It uses <<2 to convert from nibbles to bits, and then shifts the bits by that much. To handle wraparound, we OR by a copy of the number which has been shifted by the opposite amount in the opposite direciton. For example, with x=0x87654321 and n=1, the left part is shifted 4 bits to the left and becomes 0x76543210, and the right part is shifted 28 bits to the right and becomes 0x00000008, and when ORed together, the result is 0x76543218, as requested.
Edit: If - really isn't allowed, then this will get the same result (assuming an architecture with two's complement integers) without using it:
uint32_t moveNib(uint32_t x, int n) { return x<<(n<<2) | x>>((9+~n)<<2); }
Edit2: OK. Since you aren't allowed to use anything but int, how about this, then?
int moveNib(int x, int n) { return (x&0xffffffff)<<(n<<2) | (x&0xffffffff)>>((9+~n)<<2); }
The logic is the same as before, but we force the calculation to use unsigned integers by ANDing with 0xffffffff. All this assumes 32 bit integers, though. Is there anything else I have missed now?
Edit3: Here's one more version, which should be a bit more portable:
int moveNib(int x, int n) { return ((x|0u)<<((n&7)<<2) | (x|0u)>>((9+~(n&7))<<2))&0xffffffff; }
It caps n as suggested by chux, and uses |0u to convert to unsigned in order to avoid the sign bit duplication you get with signed integers. This works because (from the standard):
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
Since int and 0u have the same rank, but 0u is unsigned, then the result is unsigned, even though ORing with 0 otherwise would be a null operation.
It then truncates the result to the range of a 32-bit int so that the function will still work if ints have more bits than this (though the rotation will still be performed on the lowest 32 bits in that case. A 64-bit version would replace 7 by 15, 9 by 17 and truncate using 0xffffffffffffffff).
This solution uses 12 operators (11 if you skip the truncation, 10 if you store n&7 in a variable).
To see what happens in detail here, let's go through it for the example you gave: x=0x87654321, n=1. x|0u results in a the unsigned number 0x87654321u. (n&7)<<2=4, so we will shift 4 bits to the left, while ((9+~(n&7))<<2=28, so we will shift 28 bits to the right. So putting this together, we will compute 0x87654321u<<4 | 0x87654321u >> 28. For 32-bit integers, this is 0x76543210|0x8=0x76543218. But for 64-bit integers it is 0x876543210|0x8=0x876543218, so in that case we need to truncate to 32 bits, which is what the final &0xffffffff does. If the integers are shorter than 32 bits, then this won't work, but your example in the question had 32 bits, so I assume the integer types are at least that long.
As a small side-note: If you allow one operator which is not on the list, the sizeof operator, then we can make a version that works with all the bits of a longer int automatically. Inspired by Aki, we get (using 16 operators (remember, sizeof is an operator in C)):
int moveNib(int x, int n) {
int nbit = (n&((sizeof(int)<<1)+~0u))<<2;
return (x|0u)<<nbit | (x|0u)>>((sizeof(int)<<3)+1u+~nbit);
}
Without the additional restrictions, the typical rotate_left operation (by 0 < n < 32) is trivial.
uint32_t X = (x << 4*n) | (x >> 4*(8-n));
Since we are talking about rotations, n < 0 is not a problem. Rotation right by 1 is the same as rotation left by 7 units. Ie. nn=n & 7; and we are through.
int nn = (n & 7) << 2; // Remove the multiplication
uint32_t X = (x << nn) | (x >> (32-nn));
When nn == 0, x would be shifted by 32, which is undefined. This can be replaced simply with x >> 0, i.e. no rotation at all. (x << 0) | (x >> 0) == x.
Replacing the subtraction with addition: a - b = a + (~b+1) and simplifying:
int nn = (n & 7) << 2;
int mm = (33 + ~nn) & 31;
uint32_t X = (x << nn) | (x >> mm); // when nn=0, also mm=0
Now the only problem is in shifting a signed int x right, which would duplicate the sign bit. That should be cured by a mask: (x << nn) - 1
int nn = (n & 7) << 2;
int mm = (33 + ~nn) & 31;
int result = (x << nn) | ((x >> mm) & ((1 << nn) + ~0));
At this point we have used just 12 of the allowed operations -- next we can start to dig into the problem of sizeof(int)...
int nn = (n & (sizeof(int)-1)) << 2; // etc.

Fastest way to count number of bit transitions in an unsigned int

I'm looking for the fastest way of counting the number of bit transitions in an unsigned int.
If the int contains: 0b00000000000000000000000000001010
The number of transitions are: 4
If the int contains: 0b00000000000000000000000000001001
The number of transitions are: 3
Language is C.
int numTransitions(int a)
{
int b = a >> 1; // sign-extending shift properly counts bits at the ends
int c = a ^ b; // xor marks bits that are not the same as their neighbors on the left
return CountBits(c); // count number of set bits in c
}
For an efficient implementation of CountBits see http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
Fastest depends on your scenario:
As you specified your datatype as constant sized (unsigned int), it is possible with lookup table. But when you need this operation only once the constant overhead to init the table is too big, and scanning+counting through the int is far faster despite.
I guess the overall best would be a combination: Look up table for a byte or word (256 or 64k entries is not so much), and then combine the bytes/words by their last/first bit.
In C/C++ I would do the following:
unsigned int Transitions(unsigned int value)
{
unsigned int result = 0;
for (unsigned int markers = value ^ (value >> 1); markers; markers = markers >> 1)
{
if (markers & 0x01) result++;
}
return result;
}
Here's the code using arithmetic shift + xor and Kernighan's method for bit counting:
int count_transitions(int x)
{
assert((-1 >> 1) < 0); // check for arithmetic shift
int count = 0;
for(x ^= (x >> 1); x; x &= x - 1)
++count;
return count;
}
What language?
I would loop 64 times and then bit shift your number to inspect of the bits, then store the previous bit and compare it to the current one. If it's different, incremember your count.
Ok, with transitions you mean if you walk through the string of 0-s and 1-s, you count each occurance that a 0 follows a 1 or a 1 follows a 0.
This is easy by shifting bits out and counting the changes:
transitions(n)
result = 0
prev = n mod 2
n = n div 2
while n<>0
if n mod 2 <> prev then
result++
prev = n mod 2
fi
n = n div 2
elihw
return result
you can replace the mod and div with shifts.

Resources