CS140 Lecture notes -- Hexidecimal

  • Jim Plank
  • Lecture notes: http://www.cs.utk.edu/~cs140/notes/Types/hexi.html

    Hexidecimal

    In C, you can print out an integer in many ways using printf(). Here are four important ones:
    1. printf("%d", ... : prints it like a normal integer.

    2. printf("%c", ... : prints its ASCII character. This assumes that the integer has a value less than 256, but of course, C does not check that for you.

    3. printf("0%o", ... : prints the value in octal. By convention, I put a zero in front of octal numbers. These are numbers in base eight:
        0 in decimal is 00    in octal
        7 in decimal is 07    in octal
        8 in decimal is 010   in octal
        9 in decimal is 011   in octal
       10 in decimal is 012   in octal
       15 in decimal is 017   in octal
       16 in decimal is 020   in octal
      

    4. printf("0x%x", ... : prints the value in hexidecimal. By convention, I put 0x in front of hexidecimal numbers. These are numbers in base sixteen:
        0 in decimal is 0x0    in hexidecimal
        7 in decimal is 0x7    in hexidecimal
        8 in decimal is 0x8    in hexidecimal
        9 in decimal is 0x9    in hexidecimal
       10 in decimal is 0xa    in hexidecimal
       11 in decimal is 0xb    in hexidecimal
       12 in decimal is 0xc    in hexidecimal
       13 in decimal is 0xd    in hexidecimal
       14 in decimal is 0xe    in hexidecimal
       15 in decimal is 0xf    in hexidecimal
       16 in decimal is 0x10   in hexidecimal
       17 in decimal is 0x11   in hexidecimal
       31 in decimal is 0x1f   in hexidecimal
       32 in decimal is 0x20   in hexidecimal
      255 in decimal is 0xff   in hexidecimal
      256 in decimal is 0x100  in hexidecimal
      

    Octal

    Octal is very useful when you want to see the bit patterns of numbers. In octal, every digit stands for three bits:
    Octal digit             Bit 3       Bit 2       Bit 1
    -----------             -----       -----       -----
    00                          0           0           0
    01                          0           0           1
    02                          0           1           0
    03                          0           1           1
    04                          1           0           0
    05                          1           0           1
    06                          1           1           0
    07                          1           1           1
    
    Thus, you can "read" an integer's bit pattern very easy with an octal number. For example, 0777 means nine bits all set to one. 0755 means nine bits set as follows:
    Bit #      9 8 7  6 5 4  3 2 1
    -----      - - -  - - -  - - -
    value      1 1 1  1 0 1  1 0 1
    
    When dealing with file protections, octal is very convenient. For example if you have a file that you want to set as readable and writable by you, but only readable by the rest of the world, you will want to set it so that an ``ls -l'' says rw-r--r--. This means you want the bit pattern 110100100, which is 0644 in octal. The chmod command in fact uses octal in just this way:
    UNIX> chmod 0644 f1
    
    says to set the protection of file f1 to be rw-r--r--.

    Hexidecimal

    Hexidecimal is used mainly in one of two cases: to print out the value of a byte, and to print out the value of sequence of bytes.

    A byte is an 8-bit number. This means that it can take on any value between zero and 255. In hexidecimal, it can take on any value between 0x0 and 0xff. Thus, bytes can be represented in two hexidecimal digits. Moreover, like octal, the digits show something about the bit pattern:

    Hexidecimal digit       Bit 4       Bit 3       Bit 2       Bit 1
    -----------------       -----       -----       -----       -----
    0x0                         0           0           0           0
    0x1                         0           0           0           1
    0x2                         0           0           1           0
    0x3                         0           0           1           1
    0x4                         0           1           0           0
    0x5                         0           1           0           1
    0x6                         0           1           1           0
    0x7                         0           1           1           1
    0x8                         1           0           0           0
    0x9                         1           0           0           1
    0xa                         1           0           1           0
    0xb                         1           0           1           1
    0xc                         1           1           0           0
    0xd                         1           1           0           1
    0xe                         1           1           1           0
    0xf                         1           1           1           1
    

    Once you get used to hexidecimal, you learn how to ``read'' the bits.

    Pointers are usually shown in hexidecimal because you can ``read'' their bytes easier. On our machines, pointers are four bytes. Therefore, they can take up a maximum of 8 hexidecimal digits. When you see

    jp = 0xefffe910
    
    You can read that as four bytes: 0xef, 0xff, 0xe9 and 0x10. Lots of bits are set. In fact, the highest 16 bits are 1110 1111 1111 1111. If bit patterns mean anything, you can get it from the hex.

    How about 0x1000? This is 4096. When you see a bunch of zeros at the end of a hexidecimal number, you know it is a big power of two. Similarly, when you see a bunch of f's at the end, you know it is a power of 2, minus one. If the last digit is 0, 4, 8, or c, then the number is divisible by 4. If the last digit is 0 or 8, then the number is divisible by 8.


    Practice

    Write a program that lets you input a number in decimal, and then it prints out: Get used to these things.