Printing Hex Values (Lang: C)

Programming, for all ages and all languages.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Printing Hex Values (Lang: C)

Post by Octacone »

I need some help.
How do I print hexadecimal values such as 0x0126789DEF or 0x02 or 0x00000CF?
I can print strings and characters, but don't know how to do that.
I was thinking like:

Code: Select all

void Screen_Print_Hex(uint32_t number, uint8_t text_color)
{
   string thingToPrint = ConvertToStringFromHex(number);  --> I don't know how to convert this hex into a string
   Screen_Print_String(thingToPrint, text_color);
}
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Mikumiku747
Member
Member
Posts: 64
Joined: Thu Apr 16, 2015 7:37 am

Re: Printing Hex Values (Lang: C)

Post by Mikumiku747 »

Hex numbers are used for the very reason that a hex digit represents exactly 4 bits (There's 16 combinations of 4 bits, so we use 16 different digits to represent them, 0-9 and A-F). So, in order to print a hex number, you just need to take the number you want to print, 4 bits at a time, and convert it from the integer 0-15 to the characters '0' to '9' and then 'A' to 'F'. To get the number 4 bits at a time, you just shift and mask it, eg.

Code: Select all

uint8_t test = 0x3F //This is the number we want to print.
char index[16] = {'0', '1', '2', '3', '4', ... 'E', 'F'}; //We use this to convert the number 0-15 into a character. 
print_string("0x");
print_character(index[(test & 0xF0)>>4]);
print_character(index[(test & 0x0F)>>0]);
.. or something like that. I'm sure you can figure out for yourself how to do it for other kinds of numbers. Notice that I do the higher 4 bits first, otherwise the number might come out backwards, since hex numbers are still ordered like other human readable numbers, with the most significant digit first from the left (instead of the most significant bits being higher in memory).

For printing Signed hex integers, you can check if it's negative, and use 2's complement / ABS function to get the positive value, which is then printable using the method above.

- Mikumiku747
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Printing Hex Values (Lang: C)

Post by Octacone »

Mikumiku747 wrote:Hex numbers are used for the very reason that a hex digit represents exactly 4 bits (There's 16 combinations of 4 bits, so we use 16 different digits to represent them, 0-9 and A-F). So, in order to print a hex number, you just need to take the number you want to print, 4 bits at a time, and convert it from the integer 0-15 to the characters '0' to '9' and then 'A' to 'F'. To get the number 4 bits at a time, you just shift and mask it, eg.

Code: Select all

uint8_t test = 0x3F //This is the number we want to print.
char index[16] = {'0', '1', '2', '3', '4', ... 'E', 'F'}; //We use this to convert the number 0-15 into a character. 
print_string("0x");
print_character(index[(test & 0xF0)>>4]);
print_character(index[(test & 0x0F)>>0]);
.. or something like that. I'm sure you can figure out for yourself how to do it for other kinds of numbers. Notice that I do the higher 4 bits first, otherwise the number might come out backwards, since hex numbers are still ordered like other human readable numbers, with the most significant digit first from the left (instead of the most significant bits being higher in memory).

For printing Signed hex integers, you can check if it's negative, and use 2's complement / ABS function to get the positive value, which is then printable using the method above.

- Mikumiku747
Thank you so much! I was able to implement that. But the only problem is that I can't print values like 0x02C -> I only get 0x2C. Also I tried printing 0x0123456789ABCDEF and only got "EF".
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: Printing Hex Values (Lang: C)

Post by Octocontrabass »

octacone wrote:But the only problem is that I can't print values like 0x02C -> I only get 0x2C.
What's the difference between 0x2C and 0x02C? How does your function know the difference between them?
octacone wrote:Also I tried printing 0x0123456789ABCDEF and only got "EF".
Did you write your own function, or just copy the example? The example only works for 8-bit integers.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Printing Hex Values (Lang: C)

Post by Roman »

Actually, the integer to string conversion algorithm can be generic for different bases.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Printing Hex Values (Lang: C)

Post by Octacone »

Octocontrabass wrote:
octacone wrote:But the only problem is that I can't print values like 0x02C -> I only get 0x2C.
What's the difference between 0x2C and 0x02C? How does your function know the difference between them?

I don't know, 0x02C has 1 character more than 0x2C does?
octacone wrote:Also I tried printing 0x0123456789ABCDEF and only got "EF".
Did you write your own function, or just copy the example? The example only works for 8-bit integers.
I didn't really copy it line by line, I just implemented it the way he show me to.
Why does it only work for 8-bit integers? How can it work for addresses such as 0x0000000CCCCCC?
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Printing Hex Values (Lang: C)

Post by Octacone »

Roman wrote:Actually, the integer to string conversion algorithm can be generic for different bases.
What do integers have to do with this? I am trying to convert hex numbers such as 0x2F and hex addresses such as 0x000000CCCCC to a string. Do I need to convert it into an int first?
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: Printing Hex Values (Lang: C)

Post by Octocontrabass »

octacone wrote:What do integers have to do with this?
How are you writing an OS without knowing basic data types? :shock:
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Printing Hex Values (Lang: C)

Post by Techel »

Hexadecimal, like binary, decimal, roman numerals or a tally are just a from of representing a value. A value is an abstract thing we cannot talk about without using one of the metioned representations. A int stores a value - it doesn't store a representation. A string on the other hand stores a representation of a value. Yes, you could argue that a int stores a representation too, since it's typically made of bits, but in programming it's meant to store a abstract value. Convertible into a string with hexadecimal digits or anything else.
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Printing Hex Values (Lang: C)

Post by Roman »

@octacone, an integer is — in simple words — a number that doesn't contain a point, i.e. it's not a floating point number.

An integer can be easily converted to a numeric string of any base (10, 16, 8, 2, 3, 64... whatever). By dividing it by the base and getting the remainder you can obtain the alphabet index of the rightmost symbol.

An example:
1) let the base p be 8;
2) let the number to be converted be 10 in decimal;
3) 10 mod p = 10 mod 8 = 2;
4) 10 / p mod p = 10 / 8 mod 8 = 1;
5) the result is 12, i.e. decimal 10 is octal 12.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Printing Hex Values (Lang: C)

Post by Octacone »

Octocontrabass wrote:
octacone wrote:What do integers have to do with this?
How are you writing an OS without knowing basic data types? :shock:
This is general programming, I am 100% familiar with all of those data types. Just having some troubles converting them to one another. :?
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Printing Hex Values (Lang: C)

Post by Octacone »

Techel wrote:Hexadecimal, like binary, decimal, roman numerals or a tally are just a from of representing a value. A value is an abstract thing we cannot talk about without using one of the metioned representations. A int stores a value - it doesn't store a representation. A string on the other hand stores a representation of a value. Yes, you could argue that a int stores a representation too, since it's typically made of bits, but in programming it's meant to store a abstract value. Convertible into a string with hexadecimal digits or anything else.
I know what they do and how to use them but not familiar with their conversion methods. Every integer/float/double/string represents something in binary, something that a computer can understand.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: Printing Hex Values (Lang: C)

Post by Octacone »

Roman wrote:@octacone, an integer is — in simple words — a number that doesn't contain a point, i.e. it's not a floating point number.

An integer can be easily converted to a numeric string of any base (10, 16, 8, 2, 3, 64... whatever). By dividing it by the base and getting the remainder you can obtain the alphabet index of the rightmost symbol.

An example:
1) let the base p be 8;
2) let the number to be converted be 10 in decimal;
3) 10 mod p = 10 mod 8 = 2;
4) 10 / p mod p = 10 / 8 mod 8 = 1;
5) the result is 12, i.e. decimal 10 is octal 12.
Oh my lord, what is that? :D
I really suck when it comes to converting values. The real question is how do I make 0x034FABC5556 become "0x034FABC5556"?
P.S. I know what an integer is, but you cannot make letters like A, B, C, D, E, F become an int.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Printing Hex Values (Lang: C)

Post by Roman »

octacone wrote:The real question is how do I make 0x034FABC5556 become "0x034FABC5556"?
I gave you a clue how to do that (for any base, not only hexadecimal).
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
Mikumiku747
Member
Member
Posts: 64
Joined: Thu Apr 16, 2015 7:37 am

Re: Printing Hex Values (Lang: C)

Post by Mikumiku747 »

octacone wrote:I didn't really copy it line by line, I just implemented it the way he show me to.
Why does it only work for 8-bit integers? How can it work for addresses such as 0x0000000CCCCCC?
The way I did it was merely an example, as isn't supposed to be something you do yourself. While you might be able to put it into your code in a way that works, do you actually understand why the code I wrote works? It also seems you missed the part I wrote about *why* why hexadecimal is used for representing numbers in a programming context, and that part is critical to understanding the example solution I gave. It makes it clear why the code I wrote only works for 8 bit numbers, so have a read through again and ask me about something if you don't get it.

Rather than asking "Why does it only work for bytes?", it would be better be asking about what part of the code you don't understand. People will be much happier to help you learn than to help you solve problems, since the former gives you the tools to solve problems.

Sorry if I come across as rude or mean, I'm really not trying to be, I'm just trying to get you to focus more on learning from the answers you receive, instead of using the answers to solve your problem and then moving on without thinking about why it solved the problem. As a suggestion, try reading through everything in this thread again, to make sure you understand it all, and then have a go at making a function to print an unsigned 16 bit number. Post your code here, and if you're having problems with it, I'll go through it with you to help you get it working and make sure you get the theory behind it too. :)

- Mikumiku747
Post Reply