Bit field memory usage in C - c

Why does it return with 96 and not 64?
If I sum bit of bit field I will get 64.
Edited:
The var variable has 0xFFFFFF and not 0xFFFFFFFF. -> The var variable has 0x3FFFFFFF00FFFFFF and not 0xFFFFFFFFFFFFFFFF.*
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct{
uint32_t a : 24;
uint32_t b : 20;
uint32_t c : 10;
uint32_t d : 6;
uint32_t e : 4;
}MyType_t;
int main(){
MyType_t test;
test.a = -1;
test.b = -1;
test.c = -1;
test.d = -1;
test.e = -1;
uint64_t var = *((uint64_t*)&test);
printf("MyType_t: %d bit\n", sizeof(MyType_t) * 8);//96 bit
printf("Var: %#llX\n", var);//0x3FFFFFFF00FFFFFF
return 0;
}
This code will be worked correctly:
typedef struct{
uint32_t a : 16;
uint32_t b : 16;
uint32_t c : 16;
uint32_t d : 8;
uint32_t e : 8;
}MyType_t;

The fields a and b cannot possibly fit into a single type of uint32_t:
typedef struct{
uint32_t a : 24; //first 32 bits
uint32_t b : 20; //second 32 bits
uint32_t c : 10; //
uint32_t d : 6; //third 32 bits
uint32_t e : 4; //
}MyType_t;
so the size of the struct is three times the size of uint32_t.
The behavior of the code uint64_t var = *((uint64_t*)&test); is not defined.

Related

conversion from 'long long unsigned int' to 'long long unsigned int:40' changes value from '0xFFFFFFFFFFFFFFFF' to '0xFFFFFFFFFF' [-Werror=overflow]

I have this example code that throws an error when I try to fix one of the GCC warnings
#include <stdint.h>
//
typedef union someStruct
{
uint64_t All;
struct
{
uint64_t Foo : 40;
uint64_t Bar : 24;
} Field;
} someStruct;
#define bits_64 ((uint64_t)(-1))
//
typedef union bits
{
uint64_t oneBit: 1;
uint64_t twoBits: 2;
uint64_t threeBits: 3;
uint64_t fourBits: 4;
uint64_t fiveBits: 5;
uint64_t sixBits: 6;
uint64_t sevenBits: 7;
uint64_t fourtyBits: 40;
uint64_t All;
} bits;
#define bits_40 (((bits)(-1)).fourtyBits)
//
int main()
{
someStruct x;
someStruct y;
x.Field.Foo = bits_64; //-Woverflow warning
//trying to fix the warning with using the bits union
y.Field.Foo = bits_40; // but this throws the error msg below
/*
<source>:30:19: error: cast to union type from type not present in union
30 | #define bits_40 (((bits)(-1)).fourtyBits)
| ^
*/
return 0;
}
How can I use a union to define any number of bits and assign it to any struct field?
P.S. I cannot use enums and/or define a union variable; I have to use macros this way to fit the codebase.
Your #define for bits_40 should look like this:
#define bits_40 (((bits){.All = -1)).fourtyBits)
You could also just do:
#define bits_40 ((1ULL << 40) - 1)
and skip the bits struct entirely. Or you could define a BIT_MASK macro as follows:
#define BIT_MASK(bits) ((1uLL << bits) - 1)
:
:
x.Field.Foo = BIT_MASK(40);

generate monochrome bitmap image using c

I am writing code to generate monochrome bmp image out of array. there are plenty of tools to generate bmp to array but i want it in reverse way. i found lots of code but it was color image.
here is code i am trying...
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#define _height 64
#define _width 128
#define _bitsperpixel 1
#define _planes 1
#define _compression 0
#define _pixelbytesize _height*_width*_bitsperpixel/8
#define _filesize _pixelbytesize+sizeof(bitmap)
#define _xpixelpermeter 0x130B //2835 , 72 DPI
#define _ypixelpermeter 0x130B //2835 , 72 DPI
#define pixel 0x55
#pragma pack(push,1)
unsigned char arr[8192]={0};
typedef struct{
uint8_t signature[2];
uint32_t filesize;
uint32_t reserved;
uint32_t fileoffset_to_pixelarray;
} fileheader;
typedef struct{
uint32_t dibheadersize;
uint32_t width;
uint32_t height;
uint16_t planes;
uint16_t bitsperpixel;
uint32_t compression;
uint32_t imagesize;
uint32_t ypixelpermeter;
uint32_t xpixelpermeter;
uint32_t numcolorspallette;
uint32_t mostimpcolor;
} bitmapinfoheader;
typedef struct {
fileheader fileheader;
bitmapinfoheader bitmapinfoheader;
} bitmap;
#pragma pack(pop)
int main (int argc , char *argv[]) {
int i;
FILE *fp = fopen("test.bmp","wb");
bitmap *pbitmap = (bitmap*)calloc(1,sizeof(bitmap));
uint8_t *pixelbuffer = (uint8_t*)malloc(_pixelbytesize);
strcpy(pbitmap->fileheader.signature,"BM");
pbitmap->fileheader.filesize = _filesize;
pbitmap->fileheader.fileoffset_to_pixelarray = sizeof(bitmap);
pbitmap->bitmapinfoheader.dibheadersize =sizeof(bitmapinfoheader);
pbitmap->bitmapinfoheader.width = _width;
pbitmap->bitmapinfoheader.height = _height;
pbitmap->bitmapinfoheader.planes = _planes;
pbitmap->bitmapinfoheader.bitsperpixel = _bitsperpixel;
pbitmap->bitmapinfoheader.compression = _compression;
pbitmap->bitmapinfoheader.imagesize = _pixelbytesize;
pbitmap->bitmapinfoheader.ypixelpermeter = _ypixelpermeter ;
pbitmap->bitmapinfoheader.xpixelpermeter = _xpixelpermeter ;
pbitmap->bitmapinfoheader.numcolorspallette = 0;
fwrite (pbitmap, 1, sizeof(bitmap),fp);
for(i=0;i<8192;i++)
{
pixelbuffer[i] = arr[i];
}
// memset(pixelbuffer,pixel,_pixelbytesize);
fwrite(pixelbuffer,1,_pixelbytesize,fp);
fclose(fp);
free(pbitmap);
free(pixelbuffer);
}
i am giving bits per pixel is 1 bit (i want either black or white), and not sure about other parameters which has to be change.
if i use _bitsperpixel as 24 then it is working properly but if i assign as 1 then getting it is getting crashed..
When _bitsperpixel == 1, then _pixelbytesize == 1024. Your loop runs till 8192, thus writing beyond the allocated memory.
Depending on what you store in your arr, you should either reduce the number of iterations of the loop to _pixelbytesize, or convert your bytes in arr into bits:
for(int i = 0; i < _pixelbytesize; ++i)
{
uint8_t b = 0;
for(int j = 0; j < 8; ++j)
b |= arr[8*i + j] >> 7 << j;
pixelbuffer[i] = b;
}
Note that this is a simple code that works only for image widths that are divisible by eight.

I don't understand the behavior of this C code (union with 2 bit-field structs, a word and a byte array)

I have the following piece of code in C:
typedef union _REG_CiFIFOCON {
struct {
uint32_t RxNotEmptyIE : 1;
uint32_t RxHalfFullIE : 1;
uint32_t RxFullIE : 1;
uint32_t RxOverFlowIE : 1;
uint32_t unimplemented1 : 1;
uint32_t RxTimeStampEnable : 1;
uint32_t unimplemented2 : 1;
uint32_t TxEnable : 1;
uint32_t UINC : 1;
uint32_t unimplemented3 : 1;
uint32_t FRESET : 1;
uint32_t unimplemented4 : 13;
uint32_t FifoSize : 5;
uint32_t PayLoadSize : 3;
} rxBF;
struct {
uint32_t TxNotFullIE : 1;
uint32_t TxHalfFullIE : 1;
uint32_t TxEmptyIE : 1;
uint32_t unimplemented1 : 1;
uint32_t TxAttemptIE : 1;
uint32_t unimplemented2 : 1;
uint32_t RTREnable : 1;
uint32_t TxEnable : 1;
uint32_t UINC : 1;
uint32_t TxRequest : 1;
uint32_t FRESET : 1;
uint32_t unimplemented3 : 5;
uint32_t TxPriority : 5;
uint32_t TxAttempts : 2;
uint32_t unimplemented4 : 1;
uint32_t FifoSize : 5;
uint32_t PayLoadSize : 3;
} txBF;
uint32_t word;
uint8_t byte[4];
} REG_CiFIFOCON;
Both structs are 32 bit, so it is the word variable and the byte array (as this is composed of 4 bytes. 4x8 = 32 bits).
My problem is: I don't understand the behavior of this union. I know how to access the bits in each struct and both the word and the array, but how are they related? I know that if there was only 1 struct and the word, setting the word to some value would modify accordingly the bit fields (and viceversa), but I don't know what happens in this case.
Thank you and have a nice day!
You have 4 types in the same union. All of them are using the same memory.
It doesn't matter which one of them you change - it will affect the others.
The size of your type is 32 bytes - which in your case is also the size of every type inside it. Otherwise - it will be the size of the largest type inside.

Print full uint32_t in hex from struct bitfield

I have a structure like below:
struct myCoolStuff{
uint32_t stuff1 : 4;
uint32_t stuff2 : 4;
uint32_t stuff3 : 24;
uint32_t differentField;
}
How can I combine these fields into a hex format for printing to the screen or writing out to a file? Thank you.
struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233, .differentField=99};
printf("my combined stuff is: %x\n", <combined stuff>);
printf("My full field is: %x\n", data.differentField);
Expected Output:
my combined stuff is: 0xFF66112233
My different field is: 99
First, you can't get 0xFF out of 0xFF after you put it in a 4-bit variable. 0xFF takes 8 bits. Same for 0x66.
As for reinterpretting the bitfields as a single integer, you could,
in a very nonportable fashion (there's big-endian/little-endian issues and the possibility of padding bits) use a union.
( This:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
struct myCoolStuff{
union{
struct {
uint32_t stuff1 : 4;
uint32_t stuff2 : 4;
uint32_t stuff3 : 24;
};
uint32_t fullField;
};
};
struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233};
int main()
{
printf("My full field is: %" PRIX32 "\n", data.fullField);
}
prints 1122336F on my x86_64. )
To do it portably you can simply take the bitfields and put them together manually:
This:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
struct myCoolStuff{
uint32_t stuff1 : 4;
uint32_t stuff2 : 4;
uint32_t stuff3 : 24;
};
struct myCoolStuff data = {.stuff1=0xFF, .stuff2=0x66, .stuff3=0x112233};
int main()
{
uint32_t fullfield = data.stuff1 << 28 | data.stuff2 << 24 | data.stuff3;
printf("My full field is: %" PRIX32 "\n", fullfield);
}
should print F6112233 anywhere where it compiles (uint32_t isn't guaranteed to exist (although on POSIX platforms it will); uint_least32_t would've been more portable.)
Be careful to make sure data.stuff1 has enough bits to be shiftable by 28. Yours does because it's typed uint32_t, but it would be safer to do it e.g., with (data.stuff1 + 0UL)<<28 or (data.stuff1 + UINT32_C(0))<<28 and same for the second shift.
Add a union inside of this struct that you can use to reinterpret the fields.
struct myCoolStuff{
union {
struct {
uint32_t stuff1 : 4;
uint32_t stuff2 : 4;
uint32_t stuff3 : 24;
};
uint32_t stuff;
}
uint32_t fullField;
};
...
printf("my combined stuff is: %x\n", data.stuff);
Multiply (using at least uint32_t math) and then print using the matching specifier.
#include <inttypes.h>
struct myCoolStuff{
uint32_t stuff1 : 4;
uint32_t stuff2 : 4;
uint32_t stuff3 : 24;
uint32_t differentField;
}
uint32_t combined stuff = ((uint32_t) data.stuff1 << (4 + 24)) |
((uint32_t) data.stuff2 << 24) | data.stuff3;
printf("my combined stuff is: 0x%" PRIX32 "\n", combined stuff);
printf("My full field is: %x\n", data.differentField);
Maybe something like this will help :
unsigned char *ptr = (unsigned char *)&data; // store start address
int size = sizeof(myCoolStuff); // get size of struct in bytes
while(size--) // for each byte
{
unsigned char c = *ptr++; // get byte value
printf(" %x ", (unsigned)c); // print byte value
}

multi-precision multiplication in CUDA

I am trying to implement multi-precision multiplication in CUDA. For doing that, I have implemented a kernel which should compute multiplication of uint32_t type operand with 256-bit operand and put the result in 288-bit array. So far, I have came up with this code:
__device__ __constant__ UN_256fe B_const;
__global__ void multiply32x256Kernel(uint32_t A, UN_288bite* result){
uint8_t tid = blockIdx.x * blockDim.x + threadIdx.x;
//for managing warps
//uint8_t laineid = tid % 32;
//allocate partial products into array of uint64_t
__shared__ uint64_t partialMuls[8];
uint32_t carry, r;
if((tid < 8) && (tid != 0)){
//compute partial products
partialMuls[tid] = A * B_const.uint32[tid];
//add partial products and propagate carry
result->uint32[8] = (uint32_t)partialMuls[7];
r = (partialMuls[tid] >> 32) + ((uint32_t)partialMuls[tid - 1]);
carry = r < (partialMuls[tid] >> 32);
result->uint32[0] = (partialMuls[0] >> 32);
while(__any(carry)){
r = r + carry;
//new carry?
carry = r < carry;
}
result->uint32[tid] = r;
}
and my data-type is :
typedef struct UN_256fe{
uint32_t uint32[8];
}UN_256fe;
typedef struct UN_288bite{
uint32_t uint32[9];
}UN_288bite;
My kernel works, but it gives me wrong result. I cannot debug inside the kernel, so I would appreciate if someone let me know where the problem is or how I can debug my code inside the kernel on tegra-ubuntu with cuda-6.0.
Thanks
This answer has nothing to do with CUDA itself, but is a general C implementation.
I can't quite follow what you are doing (especially with carry) but you could try this snippet based on my own big num functions. I defined dtype to make it easier to test with smaller fields. Note that I don't specifically use a carry, but carry forward the partial product.
// little-endian
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#define dtype uint8_t // for testing
//#define dtype uint32_t // for proper ver
#define SHIFTS (sizeof(dtype)*CHAR_BIT)
#define NIBBLES (SHIFTS/4)
#define ARRLEN 8
typedef struct UN_256fe {
dtype uint[ARRLEN];
} UN_256fe;
typedef struct UN_288bite {
dtype uint[ARRLEN+1];
} UN_288bite;
void multiply(UN_288bite *product, UN_256fe *operand, dtype multiplier)
{
int i;
uint64_t partial = 0;
for (i=0; i<ARRLEN; i++) {
partial = partial + (uint64_t)multiplier * operand->uint[i];
product->uint[i] = (dtype)partial;
partial >>= SHIFTS; // carry
}
product->uint[i] = (dtype)partial;
}
int main(void)
{
int i;
dtype multiplier = 0xAA;
UN_256fe operand = { 1, 2, 3, 4, 5, 6, 7, 8};
UN_288bite product;
multiply(&product, &operand, multiplier);
for(i=ARRLEN-1; i>=0; i--)
printf("%0*X", NIBBLES, operand.uint[i]);
printf("\n * %0*X = \n", NIBBLES, multiplier);
for(i=ARRLEN; i>=0; i--)
printf("%0*X", NIBBLES, product.uint[i]);
printf("\n");
return 0;
}
Program output for uint8_t
0807060504030201
* AA =
0554A9FF54A9FF54AA

Resources