Thread: Question about the wierd number representations

  1. #1
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256

    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.

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    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.)
    Last edited by itsme86; 04-07-2005 at 04:08 PM.
    If you understand what you're doing, you're not learning anything.

  3. #3
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    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?

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    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;
    Last edited by itsme86; 04-07-2005 at 04:41 PM.
    If you understand what you're doing, you're not learning anything.

  5. #5
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    Alright. It was long shot. Thanks for at least helping.

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    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
    Last edited by itsme86; 04-07-2005 at 04:47 PM.
    If you understand what you're doing, you're not learning anything.

  7. #7
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    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.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Shouldn't you use CHAR_BIT instead of the value 8?

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    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
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  10. #10
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    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.
    If you understand what you're doing, you're not learning anything.

  11. #11
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    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;
    }
    Last edited by itsme86; 04-07-2005 at 08:09 PM.
    If you understand what you're doing, you're not learning anything.

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    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.
    Last edited by Dave_Sinkula; 04-07-2005 at 09:41 PM. Reason: Minor tweaks.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    union foo
    {
        int bar;
        unsigned char baz[ sizeof( int ) ];
    };


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User samGwilliam's Avatar
    Join Date
    Feb 2002
    Location
    Newport
    Posts
    382
    Quote Originally Posted by quzah
    Code:
    union foo
    {
        int bar;
        unsigned char baz[ sizeof( int ) ];
    };


    Quzah.
    Bravo! I like!
    Current Setup: Win 10 with Code::Blocks 17.12 (GNU GCC)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. memory issue
    By t014y in forum C Programming
    Replies: 2
    Last Post: 02-21-2009, 12:37 AM
  2. scanf oddities
    By robwhit in forum C Programming
    Replies: 5
    Last Post: 09-22-2007, 01:03 AM
  3. Issue w/ Guess My Number Program
    By mkylman in forum C++ Programming
    Replies: 5
    Last Post: 08-23-2007, 01:31 AM
  4. help with number menu
    By j4k50n in forum C Programming
    Replies: 12
    Last Post: 04-17-2007, 01:33 AM
  5. Question about limiting the number of user inputs in C
    By chobibo in forum C Programming
    Replies: 15
    Last Post: 08-30-2006, 12:37 AM