Setting a bit in an uint64_t in c - c

Hello I would like to set a bit ( value ) at a pos ( from left to right ). Here is my code that doesn't work for uint64_t ( here it should return 0 and not 1 ) but when I change values to make it works ( with the same logic ) with uint8_t it works. Any ideas? Please.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
int main()
{
uint64_t x = (uint64_t)1;
int pos = 63;
bool value = 0;
uint8_t z = x;
z = z >> (64-pos);
z = z << (64-pos);
uint64_t a = (uint64_t)1;
uint64_t d = (uint64_t)0;
uint64_t y;
uint64_t c = d;
uint64_t b = x;
b = b << (pos+1);
b = b >> (pos+1);
if (value == 1)
{
y = a;
y = y << (63-pos);
}
else
{
y=d;
}
c = c|z|y|b;
printf("%lld",c);
return c;
}
EDIT : I think there is a misunderstood ( I haven't be clear enough, my bad ), actually I have x that is an uint64_t and I have a int pos that is the position of one bit in x, and I have value that is a boolean ( 1 or 0 ) and if value is 1 the bit at the pos in x must become/stay 1 and if value is 0 the bit at the pos in x must become/stay 0.

To set the bit pos in value, you use
value |= ((uint64_t)1) << pos;
What is the rest of your code supposed to do?
For the updated question, see this answer.

//sets the bit pos to the value. if value is == 0 it zeroes the bit if value !=0 it sets the bit
void setbit(uint64_t *val, int bit, int value)
{
if(value)
{
*val |= ((uint64_t)1 << bit);
}
else
{
*val &= ~((uint64_t)1 << bit);
}
}
//sets nbits at location pos to the value of the first nbits of the value parameter.pos + nbits < 63
void setbits(uint64_t *val, int pos, int nbits, uint64_t value)
{
uint64_t mask = ((uint64_t)((uint64_t)1 << nbits) - 1);
*val &= ~(mask << pos);
*val |= (val & mask) << pos;
}
And usage with bool
#include <stdbool.h>
uint64_t obj;
/* ... */
setbit(&obj, 5, true); //sets the 5th bit to 1
setbit(&obj, 7, false); //sets the 7th bit to 0

Related

Interleave 4 byte ints to 8 byte int

I'm currently working to create a function which accepts two 4 byte unsigned integers, and returns an 8 byte unsigned long. I've tried to base my work off of the methods depicted by this research but all my attempts have been unsuccessful. The specific inputs I am working with are: 0x12345678 and 0xdeadbeef, and the result I'm looking for is 0x12de34ad56be78ef. This is my work so far:
unsigned long interleave(uint32_t x, uint32_t y){
uint64_t result = 0;
int shift = 33;
for(int i = 64; i > 0; i-=16){
shift -= 8;
//printf("%d\n", i);
//printf("%d\n", shift);
result |= (x & i) << shift;
result |= (y & i) << (shift-1);
}
}
However, this function keeps returning 0xfffffffe which is incorrect. I am printing and verifying these values using:
printf("0x%x\n", z);
and the input is initialized like so:
uint32_t x = 0x12345678;
uint32_t y = 0xdeadbeef;
Any help on this topic would be greatly appreciated, C has been a very difficult language for me, and bitwise operations even more so.
This can be done based on interleaving bits, but skipping some steps so it only interleaves bytes. Same idea: first spread out the bytes in a couple of steps, then combine them.
Here is the plan, illustrated with my amazing freehand drawing skills:
In C (not tested):
// step 1, moving the top two bytes
uint64_t a = (((uint64_t)x & 0xFFFF0000) << 16) | (x & 0xFFFF);
// step 2, moving bytes 2 and 6
a = ((a & 0x00FF000000FF0000) << 8) | (a & 0x000000FF000000FF);
// same thing with y
uint64_t b = (((uint64_t)y & 0xFFFF0000) << 16) | (y & 0xFFFF);
b = ((b & 0x00FF000000FF0000) << 8) | (b & 0x000000FF000000FF);
// merge them
uint64_t result = (a << 8) | b;
Using SSSE3 PSHUFB has been suggested, it'll work but there is an instruction that can do a byte-wise interleave in one go, punpcklbw. So all we need to really do is get the values into and out of vector registers, and that single instruction will then just care of it.
Not tested:
uint64_t interleave(uint32_t x, uint32_t y) {
__m128i xvec = _mm_cvtsi32_si128(x);
__m128i yvec = _mm_cvtsi32_si128(y);
__m128i interleaved = _mm_unpacklo_epi8(yvec, xvec);
return _mm_cvtsi128_si64(interleaved);
}
With bit-shifting and bitwise operations (endianness independent):
uint64_t interleave(uint32_t x, uint32_t y){
uint64_t result = 0;
for(uint8_t i = 0; i < 4; i ++){
result |= ((x & (0xFFull << (8*i))) << (8*(i+1)));
result |= ((y & (0xFFull << (8*i))) << (8*i));
}
return result;
}
With pointers (endianness dependent):
uint64_t interleave(uint32_t x, uint32_t y){
uint64_t result = 0;
uint8_t * x_ptr = (uint8_t *)&x;
uint8_t * y_ptr = (uint8_t *)&y;
uint8_t * r_ptr = (uint8_t *)&result;
for(uint8_t i = 0; i < 4; i++){
*(r_ptr++) = y_ptr[i];
*(r_ptr++) = x_ptr[i];
}
return result;
}
Note: this solution assumes little-endian byte order
You could do it like this:
uint64_t interleave(uint32_t x, uint32_t y)
{
uint64_t z;
unsigned char *a = (unsigned char *)&x; // 1
unsigned char *b = (unsigned char *)&y; // 1
unsigned char *c = (unsigned char *)&z;
c[0] = a[0];
c[1] = b[0];
c[2] = a[1];
c[3] = b[1];
c[4] = a[2];
c[5] = b[2];
c[6] = a[3];
c[7] = b[3];
return z;
}
Interchange a and b on the lines marked 1 depending on ordering requirement.
A version with shifts, where the LSB of y is always the LSB of the output as in your example, is:
uint64_t interleave(uint32_t x, uint32_t y)
{
return
(y & 0xFFull)
| (x & 0xFFull) << 8
| (y & 0xFF00ull) << 8
| (x & 0xFF00ull) << 16
| (y & 0xFF0000ull) << 16
| (x & 0xFF0000ull) << 24
| (y & 0xFF000000ull) << 24
| (x & 0xFF000000ull) << 32;
}
The compilers I tried don't seem to do a good job of optimizing either version so if this is a performance critical situation then maybe the inline assembly suggestion from comments is the way to go.
use union punning. Easy for the compiler to optimize.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
typedef union
{
uint64_t u64;
struct
{
union
{
uint32_t a32;
uint8_t a8[4]
};
union
{
uint32_t b32;
uint8_t b8[4]
};
};
uint8_t u8[8];
}data_64;
uint64_t interleave(uint32_t a, uint32_t b)
{
data_64 in , out;
in.a32 = a;
in.b32 = b;
for(size_t index = 0; index < sizeof(a); index ++)
{
out.u8[index * 2 + 1] = in.a8[index];
out.u8[index * 2 ] = in.b8[index];
}
return out.u64;
}
int main(void)
{
printf("%llx\n", interleave(0x12345678U, 0xdeadbeefU)) ;
}

I am trying to read all 64 bits from a value inside a struct in little endian

I am trying to read a 64 bit value that's been stored inside of struct.value. I would like to print the value in little endian and the full 64 bit value with trailing 0s. Is there anyway to do this with printf?
struct sample{
uint8_t other values;
uint8_t other values;
uint8_t other values;
uint64_t value //Not the full struct, just sample code
}sample_t
reader(sample_t sample)
{
sample.value = 0x1234;
// I would like to print "3412000000000000"
}
NOTE: This is just sample code to get a general idea, not the actual code. I hope this is enough information to convey what I'm looking for. Thank you in advance!
Perhaps like this:
#include <stdio.h>
#include <stdint.h>
int main(void){
uint64_t n = 0x1234;
printf("%02X%02X%02X%02X%02X%02X%02X%02X\n",
(unsigned)(n & 255),
(unsigned)((n >> 8) & 255),
(unsigned)((n >> 16) & 255),
(unsigned)((n >> 24) & 255),
(unsigned)((n >> 32) & 255),
(unsigned)((n >> 40) & 255),
(unsigned)((n >> 48) & 255),
(unsigned)((n >> 56) & 255) );
return 0;
}
The above is a bit unwieldy but I solved it as a "one-liner". Here is a function implementation.
#include <stdio.h>
#include <stdint.h>
int rev_print64(uint64_t n)
{
int i;
int res;
for (i = 0; i < 8; i++) {
res = printf("%02X", (unsigned)(n & 255));
if(res != 2)
return res;
n >>= 8;
}
return 16;
}
int main(void){
rev_print64(0x1234);
printf("\n");
return 0;
}
Program output
3412000000000000
One of the possible solutions:
#include <stdio.h>
#include <inttypes.h>
int main(void) {
uint64_t value, value_to_print;
uint8_t *ptr_s = (uint8_t *)&value_to_print;
uint8_t *ptr_e = ptr_s + sizeof(value_to_print) - 1;
value = 0x1234;
// swap the bytes. tidbit: no helper variable used!
value_to_print = value;
while (ptr_s < ptr_e) {
*ptr_s ^= *ptr_e;
*ptr_e ^= *ptr_s;
*ptr_s ^= *ptr_e;
++ptr_s;
--ptr_e;
}
printf("%016"PRIx64"\n", value_to_print);
return 0;
}
printf cannot do that for you. You will have to do it yourself.
#include <stdio.h>
#include <inttypes.h>
uint64_t mirror(uint64_t value) {
uint64_t temp, mask = 0xFF;
int i;
for (i = 0; i < 8; ++i) {
temp = (temp << 8) | (value & mask) >> 8 * i;
mask <<= 8;
}
return temp;
}
int main() {
uint64_t value = 0x1234;
printf("%llx\n", value); // Outputs 1234
printf("%016llx\n", mirror(value)); // Outputs 3412000000000000
return 0;
}

cast 32bit-float to 64bit-double on system where sizeof double == sizeof float == 4

I am trying to serialize a float according to the BSON spec which only has support for 64bit double. so i need to cast my float to a double.
On a system where sizeof(double) == 8 i would just do
float f = 3.14;
serialize((double)f);
but since sizeof(double) == 4 on the my target system i have to do something like
float f = 3.14;
uint64_t d;
float32_to_float64(f, &d);
serialize(d);
i have written some test code (on a machine where sizeof(double) == 8) trying to correctly converting the float32 to float64 and storing the result as a uint64_t but i am not getting the expected result.
#include <stdio.h>
#include <stdint.h>
#define FLOAT_FRACTION_MSK 0xFFFFFF
#define DOUBLE_FRACTION_S 52 // Fraction is 52 bits
#define DOUBLE_EXPONENT_S 11 // Exponent is 11 bits
#define FLOAT_FRACTION_S 23 // Fraction is 23 bits
#define FLOAT_EXPONENT_S 8 // Exponent is 8 bits
int main(void) {
// float af = 3.14;
float af = 0.15625;
double bd = 0;
//uint8_t buff[sizeof(int64_t)] = {0};
*(uint64_t*)&bd |= (*(uint32_t*)&af & (1UL << 31)) << 32; // check sign bit
uint8_t exponent32 = (*(uint32_t*)&af & 0x7F800000) >> (FLOAT_FRACTION_S+1);
if (exponent32 == 0xFF) return 1; // Error (infiniti if fraction is zero,
// Nan ortherwise)
printf("exponent32=%.4x\n", exponent32);
int64_t temp = *(uint64_t*)&bd;
*(uint64_t*)&bd |= ((uint64_t)exponent32 << (DOUBLE_FRACTION_S+4)); //& 0x7FF0000000000000; // (33); // 28
printf("exponent64=%llx, %d\n", *(uint64_t*)&bd, (DOUBLE_FRACTION_S+4));
// Do the fraction
{
printf("fraction64=%#.8llx\n", (
(uint64_t)(
(*(uint32_t*)&af & FLOAT_FRACTION_MSK) // + ((exponent32 != 0) ? (1<<24) : 0)
) << (DOUBLE_FRACTION_S-FLOAT_FRACTION_S-4)//((52-22)-1) // 33
) );
*(uint64_t*)&bd |= (
(uint64_t)(
(*(uint32_t*)&af & FLOAT_FRACTION_MSK) // + ((exponent32 != 0) ? (1<<24) : 0)
) << (DOUBLE_FRACTION_S-FLOAT_FRACTION_S)
) ;
}
double expected = af;
printf("Original float=%#.4x, converted double=%#.8llx expected=%.8llx,\n", *(uint32_t*)&af, *(uint64_t*)&bd, *(uint64_t*)&expected);
printf("Original float=%f, converted double=%lf\n\n", af, bd);
*(uint64_t*)&bd = temp;
return 0;
}
The output of this gives Original float=0x3e200000, converted double=0x3e04000000000000 expected=3fc4000000000000,
So it seems i am missing something when converting the exponent but i am at a loss to what that is.
fixed denormals, infinites & nans
unsigned __int64 Float2Double(float v)
{
unsigned int f = *(unsigned int*)&v; // reinterpret
if ( !(f&0x7fffffff) )
return (unsigned __int64)f<<32; // return +/-0.0
unsigned int s = f>>31; // get sign
unsigned int e = ((f&0x7f800000)>>23) -128; // get exponent and unbias from 128
unsigned int m = f&0x007fffff; // get mantisa
if (e==-128)
{
// handle denormals
while ( !(m&0x00800000) )
{
m<<=1;
e--;
}
m&=0x007fffff; // remove implicit 1
e++; //
}
else
if (e==127)
{
// +/-infinity
e = 1023;
}
unsigned __int64 d = s; // store sign (in lowest bit)
d <<= 11; // make space for exponent
d |= e +1024; // store rebiased exponent
d <<= 23; // add space for 23 most significant bits of mantisa
d |= m; // store 23 bits of mantisa
d <<= 52-23; // trail zeros in place of lower significant bit of mantisa
return d;
}
After accept answer that works with all float.
Tested successfully with all float including typical normal finites, sub normals, +/- zero, +/- infinity and NaN.
#include <assert.h>
#include <math.h>
#include <stdint.h>
#define F_SIGN_SHIFT (31)
#define F_EXPO_MAX (0xFF)
#define F_EXPO_SHIFT (23)
#define F_EXPO_MASK ((uint32_t) F_EXPO_MAX << F_EXPO_SHIFT)
#define F_EXPO_BIAS (127)
#define F_SFCT_MASK (0x7FFFFF)
#define F_SFCT_IMPLIEDBIT (F_SFCT_MASK + 1)
#define D_SIGN_SHIFT (63)
#define D_EXPO_MAX (0x7FF)
#define D_EXPO_SHIFT (52)
#define D_EXPO_MASK ((uint64_t) D_EXPO_MAX << D_EXPO_SHIFT)
#define D_EXPO_BIAS (1023)
uint64_t IEEEbinary32float_to_IEEEbinary64int(float f) {
assert(sizeof f == sizeof(uint32_t));
union {
float f;
uint32_t u;
} x = { f };
uint64_t y;
y = (uint64_t) (x.u >> F_SIGN_SHIFT) << D_SIGN_SHIFT;
unsigned expo = (x.u & F_EXPO_MASK) >> F_EXPO_SHIFT;
uint32_t significant = x.u & F_SFCT_MASK;
if (expo > 0) {
if (expo == F_EXPO_MAX) { // Infinity NaN
expo = D_EXPO_MAX;
} else { // typical normal finite numbers
expo += D_EXPO_BIAS - F_EXPO_BIAS;
}
} else {
if (significant) { // Subnormal
expo += D_EXPO_BIAS - F_EXPO_BIAS + 1;
while ((significant & F_SFCT_IMPLIEDBIT) == 0) {
significant <<= 1;
expo--;
}
significant &= F_SFCT_MASK;
} else { // Zero
expo = 0;
}
}
y |= (uint64_t) expo << D_EXPO_SHIFT;
y |= (uint64_t) significant << (D_EXPO_SHIFT - F_EXPO_SHIFT);
return y;
}

Bitmask understanding in C program

I have a program that my professor gave me for a HW, and I want to see if any of y'all can explain me how bits work. Note: I don't want you guys to give me the answer; I want to learn so if you guys can explain me how this work would be awesome so I can go ahead an start on my hw.
Instructions:
a) unsigned setbits (unsigned x, int p, int n, unsigned y) that returns x with the n bits that begin at position p (right-adjusted) set to the rightmost n bits of y, leaving the other bits unchanged. Note: it does not change the values of x and y though.
b) unsigned invertbits (unsigned x, int p, int n) that returns x with the n bits that begin at position p (right-adjusted) inverted, i.e. 1 changed to 0 and vice versa, leaving the other bits unchanged. Note: it does not change the value of x though.
#include <stdio.h>
#include <limits.h>
void bit_print(int);
int pack(char, char, char, char);
char unpack(int, int);
unsigned getbits(unsigned, int, int);
void bit_print(int a){
int i;
int n = sizeof(int) * CHAR_BIT;
int mask = 1 << (n-1); // mask = 100...0
for (i=1; i<=n; i++){
putchar(((a & mask) == 0)? '0' : '1');
a <<= 1;
if (i % CHAR_BIT == 0 && i < n)
putchar(' ');
}
putchar('\n');
}
int pack(char a, char b, char c, char d){
int p=a;
p = (p << CHAR_BIT) | b;
p = (p << CHAR_BIT) | c;
p = (p << CHAR_BIT) | d;
return p;
}
char unpack(int p, int k){ // k=0, 1, 2, or 3
int n = k * CHAR_BIT; // n = 0, 8, 16, 24
unsigned mask = 255; // mask = low-order byte
mask <<= n;
return ((p & mask) >> n);
}
// getbits() extracts n bits from position p(start counting from the right-most bit) in x
unsigned getbits(unsigned x, int p, int n){
unsigned temp = x >> (p+1-n);
unsigned mask = 0;
mask = ~mask;
mask = mask << n;
mask = ~mask;
return temp & mask;
// return (x >> (p+1-n)) & ~(~0<<n);
}
int main(){
int x = 19;
printf("The binary rep. of %d is:\n", x);
bit_print(x);
int p=pack('w', 'x', 'y', 'z');
printf("\n'w', 'x', 'y', and 'z' packed together is equal to %d. Its binary rep. is:\n", p);
bit_print(p);
printf("calling unpack(p, 0) to extract the byte # 0 from the right:\n");
bit_print(unpack(p, 0));
printf("calling unpack(p, 1) to extract the byte # 1 from the right:\n");
bit_print(unpack(p, 1));
printf("calling unpack(p, 2) to extract the byte # 2 from the right:\n");
bit_print(unpack(p, 2));
printf("calling unpack(p, 3) to extract the byte # 3 from the right:\n");
bit_print(unpack(p, 3));
unsigned result = getbits(p, 20, 7);
printf("\ncalling getbits(p, 20, 7) to extract 7 bits from bit # 20 returns %d:\n", result);
bit_print(result);
return 0;
}
Using bitwise AND & , OR |, XOR ^, NOT ~ and a proper bit mask you can manipulate bits inside a variable. You will also need bit shifts >> and <<.
So let us have an example:
Let's take a 8bit var x = 0xff and try to invert its 3'rd bit:
unsigned char x = 0xff; // Our var
unsigned char mask = 1<<3; // Our mask
x = x & ~mask; // Invert mask so its value is b1111_0111
// and make a bitwise AND with x
Every bit in x keeps its value if there is 1 in a mask, and turns into 0 when masks bit value is 0. Now x value is x = 0xf7.
Using other operators you can do whatever you want with bits :)
So for example yours unpack function does:
char unpack(int p, int k){ // k - byte offset
int n = k * CHAR_BIT; // n - bit offset (k * 8)
unsigned mask = 255; // mask with all ones at first byte (0x000f)
mask <<= n; // move mask left n times;
// Now the ones are at the k'th byte
// if k = 2 => mask = 0x0f00
return ((p & mask) >> n); // Mask out k'th byte of p and remove all zeros
// from beginning.
}
When p = 0x3579 and k = 1:
n = k * CHAR_BIT; // n = 8
mask = 255; // mask = 0x000f
mask <<= n; // mask = 0x00f0
p &= mask; // p = 0x0070
p >>= n; // p = 0x0007
I hope it will help you!

How do I get bit-by-bit data from an integer value in C?

I want to extract bits of a decimal number.
For example, 7 is binary 0111, and I want to get 0 1 1 1 all bits stored in bool. How can I do so?
OK, a loop is not a good option, can I do something else for this?
If you want the k-th bit of n, then do
(n & ( 1 << k )) >> k
Here we create a mask, apply the mask to n, and then right shift the masked value to get just the bit we want. We could write it out more fully as:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
You can read more about bit-masking here.
Here is a program:
#include <stdio.h>
#include <stdlib.h>
int *get_bits(int n, int bitswanted){
int *bits = malloc(sizeof(int) * bitswanted);
int k;
for(k=0; k<bitswanted; k++){
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
bits[k] = thebit;
}
return bits;
}
int main(){
int n=7;
int bitswanted = 5;
int *bits = get_bits(n, bitswanted);
printf("%d = ", n);
int i;
for(i=bitswanted-1; i>=0;i--){
printf("%d ", bits[i]);
}
printf("\n");
}
As requested, I decided to extend my comment on forefinger's answer to a full-fledged answer. Although his answer is correct, it is needlessly complex. Furthermore all current answers use signed ints to represent the values. This is dangerous, as right-shifting of negative values is implementation-defined (i.e. not portable) and left-shifting can lead to undefined behavior (see this question).
By right-shifting the desired bit into the least significant bit position, masking can be done with 1. No need to compute a new mask value for each bit.
(n >> k) & 1
As a complete program, computing (and subsequently printing) an array of single bit values:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
unsigned
input = 0b0111u,
n_bits = 4u,
*bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
bit = 0;
for(bit = 0; bit < n_bits; ++bit)
bits[bit] = (input >> bit) & 1;
for(bit = n_bits; bit--;)
printf("%u", bits[bit]);
printf("\n");
free(bits);
}
Assuming that you want to calculate all bits as in this case, and not a specific one, the loop can be further changed to
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
This modifies input in place and thereby allows the use of a constant width, single-bit shift, which may be more efficient on some architectures.
Here's one way to do it—there are many others:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
It is hard to understand why use of a loop is not desired, but it is easy enough to unroll the loop:
bool b[4];
int v = 7; // number to dissect
b [0] = 0 != (v & (1 << 0));
b [1] = 0 != (v & (1 << 1));
b [2] = 0 != (v & (1 << 2));
b [3] = 0 != (v & (1 << 3));
Or evaluating constant expressions in the last four statements:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
Here's a very simple way to do it;
int main()
{
int s=7,l=1;
vector <bool> v;
v.clear();
while (l <= 4)
{
v.push_back(s%2);
s /= 2;
l++;
}
for (l=(v.size()-1); l >= 0; l--)
{
cout<<v[l]<<" ";
}
return 0;
}
Using std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
#prateek thank you for your help. I rewrote the function with comments for use in a program. Increase 8 for more bits (up to 32 for an integer).
std::vector <bool> bits_from_int (int integer) // discern which bits of PLC codes are true
{
std::vector <bool> bool_bits;
// continously divide the integer by 2, if there is no remainder, the bit is 1, else it's 0
for (int i = 0; i < 8; i++)
{
bool_bits.push_back (integer%2); // remainder of dividing by 2
integer /= 2; // integer equals itself divided by 2
}
return bool_bits;
}
#include <stdio.h>
int main(void)
{
int number = 7; /* signed */
int vbool[8 * sizeof(int)];
int i;
for (i = 0; i < 8 * sizeof(int); i++)
{
vbool[i] = number<<i < 0;
printf("%d", vbool[i]);
}
return 0;
}
If you don't want any loops, you'll have to write it out:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num = 7;
#if 0
bool arr[4] = { (num&1) ?true: false, (num&2) ?true: false, (num&4) ?true: false, (num&8) ?true: false };
#else
#define BTB(v,i) ((v) & (1u << (i))) ? true : false
bool arr[4] = { BTB(num,0), BTB(num,1), BTB(num,2), BTB(num,3)};
#undef BTB
#endif
printf("%d %d %d %d\n", arr[3], arr[2], arr[1], arr[0]);
return 0;
}
As demonstrated here, this also works in an initializer.

Resources