# Question about the wierd number representations

• 04-07-2005
Jaken Veina
Question about the wierd number representations
What's the deal with numbers like
Code:

`0x5fffffff`
?

I mean, I can tell that it's just another way of representing a number, and from how I've seen them used, I'm guessing they're a way of representing individual bit/byte values. But how in the heck do they work? I see letters in there, so I'm guessing maybe hexadecimal? Can anyone enlighten me, cause it would really help me with a custom library I'm writing. Thanks.
• 04-07-2005
itsme86
Any constant that begins with 0x is considered a hex value, so yeah, it's hex. Hex is very nice for working with bits because you can nicely slice a bunch of bits into multiples of 4. Every hex digit represents 4 bits (F (hex) = 15 (dec) = 1111 (binary)).

You count in hex like so:
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 ...

so A = 10 dec, B = 11 dec, etc. and 10 hex = 16 dec.

You could also use 1610612735 instead of 0x5fffffff (since they're equivalent), but which is really easier to read? Using the hex value you can tell immediately that it's likely a bit mask (because each f is 4 binary 1s so you've got 7 * 4 1s all in a row) and it's meant to mask a 32-bit value (8 hex digits * 4 bits each). The decimal equivalent doesn't tell you any of that (not me, anyway.)
• 04-07-2005
Jaken Veina
Mmm-kay. So it is just simple hexadecimal representation. I'll play around with those for a while. But I do have another question, now.

I'm working with a structure that's currently 56 bytes in size (huge, I know, but I should be able to cut a bunch of it off). Now, instead of testing each element of the to the value, if I defined a single hexadecimal number and tested it against only the first element of the structure, would it include the bits of the second element after the first and add those to the test? That's complicated. Let me give an example.
Code:

```struct examp  {   unsigned char a = 170; //1010 1010   unsigned char b = 204; //1100 1100   unsigned char c = 219; //1101 1011  }; #define TEST 0xAACCDB //1010 1010 1100 1100 1101 1011```
Now, if I said
Code:

`if(examp.a == TEST)`
seeing as TEST is much larger than examp.a, would the computer automatically include the next item in the structure into the test? In terms of this example, would the computer actually test the value of examp.a, examp.b, and examp.c displayed consecutively?
• 04-07-2005
itsme86
Usually all of the members of a struct are aligned on word boundaries, so no. You'd end up with 1 byte for a member and then 3 bytes of padding, then 1 byte for your b member and then 3 bytes of padding, and so on.

Most compilers allow you to define your struct as "packed" which means there won't be any padding. In gcc, you add something like _attribute_packed_ to the struct definition, but I don't remember exactly what it is. If you want to get 1-byte values out of a 24-bit integer, you're better off doing something like:
Code:

```int num = 0xAACCDB; int byte1, byte2, byte3; byte1 = (num & 0xFF0000) >> 32; byte2 = (num & 0x00FF00) >> 16; byte3 = num & 0x0000FF;```
• 04-07-2005
Jaken Veina
Alright. It was long shot. Thanks for at least helping.
• 04-07-2005
itsme86
You could create a macro to grab any byte you want:
Code:

```itsme@dreams:~/C\$ cat grabbyte.c #include <stdio.h> #define GRABBYTE(n,b) (((n) & (0xFF << ((4 - (b)) * 8))) >> ((4 - (b)) * 8)) int main(void) {   unsigned int num = 0xAABBCCDD;   printf("byte1 = %X\n", GRABBYTE(num, 1));   printf("byte2 = %X\n", GRABBYTE(num, 2));   printf("byte3 = %X\n", GRABBYTE(num, 3));   printf("byte4 = %X\n", GRABBYTE(num, 4));   return 0; } itsme@dreams:~/C\$ ./grabbyte byte1 = AA byte2 = BB byte3 = CC byte4 = DD```
EDIT: 5 bonus points if you can figure out exactly how that macro works ;)
• 04-07-2005
Jaken Veina
It shifts 11111111 by 4 minus the byte which is then shifted by 4 minus the byte times 8, which makes it the correct number of bits, and tests it against n. Very good.
• 04-07-2005
quzah
Shouldn't you use CHAR_BIT instead of the value 8?

Quzah.
• 04-07-2005
Dave_Sinkula
Quote:

Originally Posted by Jaken Veina
I'm working with a structure that's currently 56 bytes in size (huge, I know, but I should be able to cut a bunch of it off). Now, instead of testing each element of the to the value, if I defined a single hexadecimal number and tested it against only the first element of the structure, would it include the bits of the second element after the first and add those to the test?

http://www.eskimo.com/~scs/C-faq/q2.8.html
• 04-07-2005
itsme86
Quote:

Originally Posted by quzah
Shouldn't you use CHAR_BIT instead of the value 8?

Quzah.

I was merely interested in splitting a 32-bit integer into 4 equal parts. Is it possible for an int's size to not be a multiple of 8? I was actually more concerned with the possibility of using sizeof(int) than replacing 8 with CHAR_BIT. From what I understand the size of an int doesn't necessarly have to be a multiple of CHAR_BIT, but maybe I'm mistaken.

How would you write it and why? I'm not 100% sure on the use of CHAR_BIT so maybe this conversation could enlighten me.
• 04-07-2005
itsme86
By the way, I wrote that macro in a rush at work. Here's a little better way to write it:
Code:

```#include <stdio.h> /* #define GRABBYTE(n,b) (((n) & (0xFF << ((4 - (b)) * 8))) >> ((4 - (b)) * 8)) */ #define GRABBYTE(n,b) (((n) >> ((sizeof(int) - (b)) * 8)) & 0xFF) int main(void) {   unsigned int num = 0xAABBCCDD;   int i;   for(i = 1;i <= sizeof(int);++i)     printf("byte%d = %X\n", i, GRABBYTE(num, i));   return 0; }```
• 04-07-2005
Dave_Sinkula
Quote:

Originally Posted by itsme86
Is it possible for an int's size to not be a multiple of 8? I was actually more concerned with the possibility of using sizeof(int) than replacing 8 with CHAR_BIT. From what I understand the size of an int doesn't necessarly have to be a multiple of CHAR_BIT, but maybe I'm mistaken.

It is possible for an int's size not to be a multiple of 8. It is possible that CHAR_BIT is not 8. It is also possible that all of the bits of the object representation do not contribute to the value. So while you could use CHAR_BIT and sizeof(int) to determine the number of bits in the object representation, not all of those bits might be relevant to the value.
Quote:

Originally Posted by itsme86
How would you write it and why?

Maybe like one of these.
• 04-07-2005
quzah
Code:

```union foo {     int bar;     unsigned char baz[ sizeof( int ) ]; };```
;)

Quzah.
• 04-07-2005
samGwilliam
Quote:

Originally Posted by quzah
Code:

```union foo {     int bar;     unsigned char baz[ sizeof( int ) ]; };```
;)

Quzah.

Bravo! I like! :cool: