Converting hex to decimal

Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Nov 2008
Posts: 11
Reputation: oling is an unknown quantity at this point 
Solved Threads: 0
oling oling is offline Offline
Newbie Poster

Converting hex to decimal

 
0
  #1
Sep 21st, 2009
So, I am learning C and have this newby problem. This is my snippet:
  1. #include <stdio.h>
  2.  
  3. main() {
  4.  
  5. char x;
  6. unsigned y;
  7.  
  8. x=0xFF;
  9. y=0xFFFF;
  10.  
  11. printf("Size of char: %d-bits\n", sizeof(char)*4);
  12. printf("Size of int: %d-bits\n", sizeof(int)*4);
  13.  
  14. printf("\n0x%X in decimal: %d\n", x, x);
  15. printf("\n0x%X in decimal: %d\n", y, y);
  16. return 0;
  17. }
This prints:
Size of char: 4-bits
Size of int: 16-bits

0xFFFFFFFF in decimal: -1
0xFFFF in decimal: 65535

Question:
a. Why does the program deliver a 8-bit hex number (0xFFFFFFFF) when the input is 0xFF and when the sizeof() delivers char as 4-bit ?

b. The program returns 0xFFFFFFFF as -1 in decimal. However when I use a Hex-Decimal converter I get 0xFF as 255 and 0xFFFFFFFF as 4294967295?
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 1,970
Reputation: tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute 
Solved Threads: 214
tux4life's Avatar
tux4life tux4life is offline Offline
Posting Virtuoso

Re: Converting hex to decimal

 
2
  #2
Sep 21st, 2009
Question:
a. Why does the program deliver a 8-bit hex number (0xFFFFFFFF) when the input is 0xFF and when the sizeof() delivers char as 4-bit ?
This code is wrong when you want to display the size of a char (in bits):
  1. printf("Size of char: %d-bits\n", sizeof(char)*4);
Sure it will report that a char variable consists out of 4 bits, but there's something wrong with your code, for example: how did you come up with this magic 4? For what does it stand? Second: the sizeof operator will always (under all circumstances, on all platforms return 1 if you invoke: sizeof(char) ), so this multiplied by 4 will always give 4 as the result.
The correct way to get the correct size in bits per byte (a char is always 1 byte) is by using the CHAR_BIT macro as defined in the limits.h header (you have to include this file if you want to use the CHAR_BIT macro, you can do this by adding this directive to the top of your program: #include <limits.h> ).

The correct way of getting the size (in bits) of a variable of type char and or integer in C:

char:
  1. printf("Size of a variable of type char (in bits): %lu", CHAR_BIT);

integer:
  1. printf("Size of a variable of type integer (in bits): %lu", CHAR_BIT*sizeof(int));

What exactly does CHAR_BIT represent?
The CHAR_BIT macro represents the number of bits in a byte (a variable of type char does always have the size of one byte, as defined per standard, but this isn't the case for variables of other types, they depend on your C-implementation).
So multiplying the value of CHAR_BIT by the sizeof of a certain variable type (int, double, float...) will give you the number of bytes that type consists of.

Note that sizeof(type) returns the size (in bytes) of a variable type.
Also notice that I used the %lu format specifier in the format string passed to the printf() function, this is because the sizeof operator returns a value of an unsigned integral datatype (as defined per standard), to produce portable code I added the %lu format specifier (which will ensure a cast to an unsigned long, the biggest unsigned integral type) to make sure that the size will always be displayed correctly on the screen.
"Never argue with idiots, they just drag you down to their level and then beat you with experience."
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 11
Reputation: oling is an unknown quantity at this point 
Solved Threads: 0
oling oling is offline Offline
Newbie Poster

Re: Converting hex to decimal

 
0
  #3
Sep 21st, 2009
Thanks a lot, I had no idea that CHAR_BIT existed - I have not come this far. The only reason I uses sizeof(char)*4 was to get the number of bits. However this is not a good practice I understand (no magic numbers).

But, what about my other question. Why do I get 0xFFFFFFF and -1 as the decimal?
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 1,970
Reputation: tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute 
Solved Threads: 214
tux4life's Avatar
tux4life tux4life is offline Offline
Posting Virtuoso

Re: Converting hex to decimal

 
0
  #4
Sep 21st, 2009
Originally Posted by oling View Post
But, what about my other question. Why do I get 0xFFFFFFF and -1 as the decimal?
Oh sorry, I forgot to answer that one
Just as a convenience for anyone who's reading the thread:
b. The program returns 0xFFFFFFFF as -1 in decimal. However when I use a Hex-Decimal converter I get 0xFF as 255 and 0xFFFFFFFF as 4294967295?
Well, this is because in your code you use signed ints (that is what you get when you declare a variable by just using int a_variable_name ).
As int exists in both signed and unsigned flavors, your hex-converter was using an unsigned int to do the conversion, while in your code you have a signed int, as the name tells you it's signed, which means that it can have a sign, this isn't the case with unsigned integers which cannot have a sign.
A very non-technical explanation (but maybe less correct) is: with signed integers the high-order bit signifies whether the number is negative (high-order bit is one), or positive (high-order bit is zero).
With unsigned integers, the high-order bit is used to store another range of possible numbers.
Important to mention is that both signed and unsigned types do consume the same amount of bytes, this is also why an unsigned integer variable can store twice as huge positive values as a signed one, while a signed one can also store negative numbers.
Maybe something interesting for you to google up is: two's complement, this will give you a better insight in how the whole thing (with sign bits, etc.) works.
"Never argue with idiots, they just drag you down to their level and then beat you with experience."
Reply With Quote Quick reply to this message  
Join Date: Jun 2009
Posts: 681
Reputation: Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of Tom Gunn has much to be proud of 
Solved Threads: 133
Tom Gunn's Avatar
Tom Gunn Tom Gunn is offline Offline
Practically a Master Poster

Re: Converting hex to decimal

 
1
  #5
Sep 21st, 2009
(which will ensure a cast to an unsigned long, the biggest unsigned integral type)
Unless size_t is unsigned long or integral promotion makes it an unsigned long, the only thing you ensure is undefined behavior because the type of the value and the type of the format string do not match. The convention is to use an explicit cast:
  1. printf("%lu\n", (unsigned long)sizeof(something));
to make sure that the size will always be displayed correctly on the screen.
If you are lucky. size_t is only guaranteed to be unsigned. It might be an extended type, where there is risk of the value being truncated by casting to unsigned long. The ideal solution is C99's %z modifier:
  1. printf("%zu\n", sizeof(something));
But for C89 compilers the best we can do is cast to the largest possible unsigned type that printf() supports and hope for the best.
-Tommy (For Great Justice!) Gunn
Reply With Quote Quick reply to this message  
Join Date: May 2009
Posts: 212
Reputation: MrNoob has a little shameless behaviour in the past 
Solved Threads: 6
MrNoob's Avatar
MrNoob MrNoob is offline Offline
Posting Whiz in Training

Re: Converting hex to decimal

 
-1
  #6
Sep 21st, 2009
just make it as an atoi but change base 10 to 16 you can make it unverisal aswell that work for all bases by applying a 2nd argument in atoi copy specifying the base
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 1,970
Reputation: tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute tux4life has a reputation beyond repute 
Solved Threads: 214
tux4life's Avatar
tux4life tux4life is offline Offline
Posting Virtuoso

Re: Converting hex to decimal

 
0
  #7
Sep 21st, 2009
b. The program returns 0xFFFFFFFF as -1 in decimal. However when I use a Hex-Decimal converter I get 0xFF as 255 and 0xFFFFFFFF as 4294967295?
In my previous post I forgot to point out that 0xFFFFFFFF has a binary representation wherein every bit is one, if such a binary value goes into a signed integer variable, then the variable contains a value equivalent to -1 in decimal.
If you read about the two's complement (A must read! Google it up), you'll be able to understand why this is the case

Also thanks to Tom Gunn for pointing out a mistake in my post and providing an excellent correction
"Never argue with idiots, they just drag you down to their level and then beat you with experience."
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 11
Reputation: oling is an unknown quantity at this point 
Solved Threads: 0
oling oling is offline Offline
Newbie Poster

Re: Converting hex to decimal

 
0
  #8
Sep 21st, 2009
Originally Posted by tux4life View Post
In my previous post I forgot to point out that 0xFFFFFFFF has a binary representation wherein every bit is one, if such a binary value goes into a signed integer variable, then the variable contains a value equivalent to -1 in decimal.
If you read about the two's complement (A must read! Google it up), you'll be able to understand why this is the case

Also thanks to Tom Gunn for pointing out a mistake in my post and providing an excellent correction
I was reading through "two's complement" on a couple of sites and think I have gotten the hang of it. If I change the (signed) char variable to "unsigned" it returns 255 as expected (unsigned char x=0xFF returns 255 while char x=0xFF returns -1)

However, the strange thing, it doesn't matter whether I have the int variable signed or unsigned - the program always returns the same number:

int y=0xFFFF returns 65,535
unsigned y=0xFFFF returns 65,535 (should return -1)

Any advice?
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,461
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 254
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Converting hex to decimal

 
0
  #9
Sep 21st, 2009
Originally Posted by oling View Post
However, the strange thing, it doesn't matter whether I have the int variable signed or unsigned - the program always returns the same number:

int y=0xFFFF returns 65,535
unsigned y=0xFFFF returns 65,535 (should return -1)

Any advice?
I'm rather curious why you think an unsigned value should be negative, but do remember to try to use the correct format specifiers with printf for the data type being used.
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Nov 2008
Posts: 11
Reputation: oling is an unknown quantity at this point 
Solved Threads: 0
oling oling is offline Offline
Newbie Poster

Re: Converting hex to decimal

 
0
  #10
Sep 21st, 2009
Originally Posted by Dave Sinkula View Post
I'm rather curious why you think an unsigned value should be negative, but do remember to try to use the correct format specifiers with printf for the data type being used.
Sorry, I meant that the "signed int" should have been -1 (while unsigned is 65,535).

The printf is as follows:
printf("\n0x%X in decimal: %d\n", y, y);

(printf("\n0x%X in decimal: %u\n", y, y) returns the same (65.535)

Do I need a different format specifier in printf ?

thanks,
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:




Views: 1573 | Replies: 17
Thread Tools Search this Thread



Tag cloud for C
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC