Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
#include<stdio.h>
int main(){
struct value
{
int bit1:1;
int bit2:4;
int bit3:4;
}
bit ={1,2,2};
printf("%d %d %d \n",bit.bit1,bit.bit2,bit.bit3);
return 0;
}
Output : -1 2 2
Hi ,I am not able to understand structure bitfields.How the negative value is coming .
int bits:2;
can store 00(0), 01(1), 10(-2), 11(-1) *Assuming 2s complement system for signed
unsigned int bits:2;
can store 00(0), 01(1), 10(2), 11(3)
Bit representation of both types that can be represented is same but the interpretation is different.
You are using :1, so it can store 0 or -1, so the negative output. You are trying to store 1, which can not be represented by int :1, so the output is surprising. Takeaway is, don't do that.
Conclusion Almost always use unsigned for bitfield members. Rewrite the structure as:
struct value
{
unsigned int bit1:1;
unsigned int bit2:4;
unsigned int bit3:4;
};
bit1 in the structure is of type int. when you don't specify unsigned before int like unsigned int it will be treated as signedinteger! and for bit1 you have mentioned size as 1 bit, that means bit1 can have only 2 values! 0 and 1. when you assigned bit1 with 1, it will print -1 as type is int. as we know, for int variables if the MSB bit it set then it is a negative number!
bit2 and bit3 are of size 4 bits, So its value can be ranged from 0 till 15 (0b1111).
To know more about bit fields, please check this link: http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want a function which would help me to extract few bits or bytes from a starting bit position from a byte array. The order of the byte array is LSB. The skeleton of the code is as follows:
typedef unsigned char uint8;
typedef unsigned short uint16;
uint16 ExtractBitsOrBytes(uint16 StartBit, uint8 *ByteArray, uint16 BitsWanted)
{
uint16 Result;
...
}
How can I implement this logic in C?. Any example or starting point is much appreciated.
Your problem is not fully specified: LSB refers to the order of bytes in memory for integral types spanning more than one byte. In your case you must specify how the bits are numbered in the array and composed to form the value extracted.
It would make sense to number the bits from 0, such that bit n is the bit with value 1 << (n % 8) in the byte at offset n / 8. For consistency, the bit with the lowest number should become the least significant bit of the extracted value. This convention is consistent with LSB as extracting 16 bits at offset 0 yields the value of the uint16 stored in the first 2 bytes of the array.
Here is a naive implementation with this convention:
typedef unsigned char uint8;
typedef unsigned short uint16;
uint16 ExtractBitsOrBytes(uint16 StartBit, const uint8 *ByteArray, uint16 BitsWanted) {
// assuming BitsWanted <= 16
uint16 result = 0;
uint16 i;
for (i = 0; i < BitsWanted; i++) {
result |= (uint16)((ByteArray[StartBit >> 3] >> (StartBit & 7)) & 1) << i;
StartBit++;
}
return result;
}
Note however that the convention used for monochrome bitmaps on many systems is different: the leftmost pixel corresponds to the most significant bit of the first byte, a convention inherited from choices made in the late 70s, mixing MSB and LSB, that made graphics software more complicated than it should have been.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
this is a part of a C program that i didn't understand :
unsigned short twittlen;
int x;
x = atoi(argv[1]);
twittlen = x;
if(twittlen >= 64) {
printf("Nope , You don't know about Integer");
return -1;
}
if (x >= 64 )
printf("you got it ");
My problem is how to find an int that is greater than 64 but when converting it to unsigned short it will be less than 64 !
I looked alot about limit of those types of integers even on stackoverflow but i didn't find the answer about this !
Thanks in advance :)
When you assign an int value to an unsigned short, truncation will occur.
Assuming int is 4 bytes and short is 2, you simply need to provide the program with a value greater than 64 whose lower two bytes are less than 64.
The maximum unsigned 16-bit value is 65535:
0x0000FFFF
So if you enter the number 65536:
0x00010000
When truncated to just two bytes:
0x0000
Is zero.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to learn if this is possible:
for ex:
we have long Lvalue = 0xFF00f41a;
and also have int *p;
Can we point to last 2 byte of Lvalue
like p=&Lvalue <<16;
p pointed frist 16 bit value is it possible?
*p --> f41a;
*(p+1) --->0xFF00;
then if
p = 0xa011;
long Lvalue ---> 0xFF00a011
actually I need bit operations. I have 32 bit value but I can send only 16 bits and if I change 16 bit have to change first 16 bit last 16 bit of 32 bit value.
If you just want 16bits of the larger 32bits type, use bit mask for the task, for example, to get the lower 16 bits of value:
long value = 0xFF00f41a;
long lower = value & 0xFFFF;
To change the lower 16 bits of value, use bit operation:
lower = <some thing new>;
value = (value & 0xFFFF0000) | lower;
Don't use pointer to access part of the 32bit value, it crates undefined bahavior when you dereference it.
Following short example will work, if int is aligned on 4-bytes (which seems to be guaranteed by gcc, see Casting an int pointer to a char ptr and vice versa):
#include <stdio.h>
int main() {
int v = 0xcafe;
int *ip = &v;
char *cp = (char*) ip;
printf("%hhX\n", *cp); // FE on little-endian box
printf("%hhX\n", *(cp + 1));
*cp = 0xbe;
*(cp + 1) = 0xba;
printf("%X\n", *ip);
return 0;
}
You can guarantee alignment of int thus:
int main() {
__attribute__ ((aligned (4))) int v = 0xcafe;
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write C program that initializes a variable of type float to 1000.565300 and extracts relevant fields of the IEEE 754 representation. I should extract the sign bit (bit 31), the exponent field (bits 30 to 23) and the significant field (bits 22 to 0). I should use bit masking and shift operations to extract these fields. My program should keep the extracted fields in 32-bit unsigned integers and should print their values in the hexadecimal and binary formats. And here is my program. I do not know how to bit masking
Well, one easy way to do all this is:
Interpret a float bits as an unsigned: uint32_t num = *(uint32_t*)&value
It means: I want to treat the address of value as the address of a 32 bit unsigned and then I want to take the value stored at that address
Sign: int sign = (~(~0u>>1)&num) ? -1 : 1 //checks if first bit of float is 1 or 0 , if it's 1 then it's a negative number
exp part: uint32_t exp = num&0x7F800000
mantissa : uint32_t mant = num&0x007FFFFF
If you don't know masks :
0x7F800000 : 0 11111111 00000000000000000000000
0x007FFFFF : 0 00000000 11111111111111111111111
As for printing bits , you can use this function:
void printbits(uint32_t num)
{
for(uint32_t m=~(~0u>>1);m;m>>=1) // initial m = 100..0 then 0100..0 and so on
putchar(n&m ? '1' : '0');
putchar('\n');
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Practical Use of Zero-Length Bitfields
Why some structures have zero-width bit fields, and why is it required?
struct foo {
int a:3;
int b:2;
int :0; // Force alignment to next boundary.
int c:4;
int d:3;
};
int main()
{
int i = 0xFFFF;
struct foo *f = (struct foo *)&i;
printf("a=%d\nb=%d\nc=%d\nd=%d\n", f->a, f->b, f->c, f->d);
return 0;
}
The output of above program is
manav#os-team:~/programs/test$ ./a.out
a=-1
b=-1
c=-8
d=0
Please explain why these values are negative, and the memory layout of these variables inside the structure?
From this first hit on a Google search:
Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot be referenced or initialized. A zero-width bit field can cause the next field to be aligned on the next container boundary where the container is the same size as the underlying type of the bit field.
As for the second part of your question, you set some of the bitfields in your struct to all 1s, and since these fields are signed then this results in a negative value for these fields. You can see this more effectively if you set the entire struct to 1s and look at the values in both signed and unsigned representations, e.g.
int main()
{
struct foo f;
memset(&f, 0xff, sizeof(f));
printf("a=%d\nb=%d\nc=%d\nd=%d\n", f.a, f.b, f.c, f.d); // print fields as signed
printf("a=%u\nb=%u\nc=%u\nd=%u\n", f.a, f.b, f.c, f.d); // print fields as unsigned
return 0;
}
The memory layout is "it depends" and you can't count on any particular layout from any particular compiler. In fact, you may see different layout from any given compiler by changing its settings. Don't try to guess, intuit, or depend on the layout.
Negatives - all your elements are ints which are signed, so they are negative since you've initialized every bit to 1, so you've got sign bits set. As for d - beats me. Typo?
As stated here, zero-length bitfields add alignment between bitfields. If we have several bitfields in a row, their layout is compact, but if we want to align one of them to byte/word/dword boundary, we need to put a zero-length bitfield between this and the previous one.
Example from the link above:
struct on_off {
unsigned light : 1;
unsigned toaster : 1;
int count; /* 4 bytes */
unsigned ac : 4; // this and
unsigned : 4; // this and
unsigned clock : 1; // this bitfields are next to each other
unsigned : 0;
unsigned flag : 1; // this bitfield is at a 4 bytes boundary.
} kitchen ;
Numbers are negative because the bitfields are signed, i.e. if you have a signed char variable, its size is 8 bits which can hold 256 different values. Half of the values are positive, the rest are negative and 0. The most significant bit indicates sign (1 for negative, 0 for positive). Regarding zero-length bitfields see here: Practical Use of Zero-Length Bitfields