Technically all numbers are stored in binary because that is simply how computers operate. When numbers are to be displayed the computer has to do math to convert the number into ASCII character symbols. In other words the binary number has to be broken up into digits corresponding to whatever base is being calculated. For example if the base was ten and the number was 5463:
5463 in binary is 1 0101 0101 0111
So if the program needs to display this number to the screen the binary is going to be split up into individual digits usually by repeatedly dividing by ten and using the remainder to know the value of each digit in a right-to-left fashion.
Repeatedly dividing 5463 by 10 would give 3, 6, 4, and 5. (The repetition stops when the number is zero.)
Of course, all this math is done in binary so the digits look more like this:
3: 0011
6: 0110
4: 0100
5: 0101
These digits are converted to ASCII at some point during this process by simpling ORing the binary numbers with 110000. Info on that here at this link:
http://stackoverflow.com/questions/12903204/converting-numbers-to-ascii-in-assembly
A similar process is used for octal and hexadecimal or any other base. Just change the division to whatever base you converting to.
The tricky part is for hexadecimal when you start dividing by 16 and get remainders greater than 9. Any remainder 10 or higher can be added with 55 to get ASCII values 'A' (65) and higher.
Now this process can also work backwards for scanf's input.
When "%x" is used as the format string, the computer can convert each digit to a 4-digit binary number. Then chain all the 4-digit numbers together for the resulting binary number.