943,914 Members | Top Members by Rank

Ad:
  • C Discussion Thread
  • Unsolved
  • Views: 5197
  • C RSS
You are currently viewing page 1 of this multi-page discussion thread
Sep 21st, 2009
0

Converting hex to decimal

Expand Post »
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?
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
oling is offline Offline
13 posts
since Nov 2008
Sep 21st, 2009
2

Re: Converting hex to decimal

Quote ...
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.
Reputation Points: 2125
Solved Threads: 243
Postaholic
tux4life is offline Offline
2,105 posts
since Feb 2009
Sep 21st, 2009
0

Re: Converting hex to decimal

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?
Reputation Points: 10
Solved Threads: 0
Newbie Poster
oling is offline Offline
13 posts
since Nov 2008
Sep 21st, 2009
0

Re: Converting hex to decimal

Click to Expand / Collapse  Quote originally posted by oling ...
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:
Quote ...
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.
Reputation Points: 2125
Solved Threads: 243
Postaholic
tux4life is offline Offline
2,105 posts
since Feb 2009
Sep 21st, 2009
1

Re: Converting hex to decimal

Quote ...
(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));
Quote ...
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.
Reputation Points: 1446
Solved Threads: 135
Practically a Master Poster
Tom Gunn is offline Offline
681 posts
since Jun 2009
Sep 21st, 2009
-1

Re: Converting hex to decimal

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
Reputation Points: 34
Solved Threads: 7
Posting Whiz in Training
MrNoob is offline Offline
218 posts
since May 2009
Sep 21st, 2009
0

Re: Converting hex to decimal

Quote ...
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
Reputation Points: 2125
Solved Threads: 243
Postaholic
tux4life is offline Offline
2,105 posts
since Feb 2009
Sep 21st, 2009
0

Re: Converting hex to decimal

Click to Expand / Collapse  Quote originally posted by tux4life ...
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?
Reputation Points: 10
Solved Threads: 0
Newbie Poster
oling is offline Offline
13 posts
since Nov 2008
Sep 21st, 2009
0

Re: Converting hex to decimal

Click to Expand / Collapse  Quote originally posted by oling ...
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.
Team Colleague
Reputation Points: 2780
Solved Threads: 312
long time no c
Dave Sinkula is offline Offline
4,790 posts
since Apr 2004
Sep 21st, 2009
0

Re: Converting hex to decimal

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,
Reputation Points: 10
Solved Threads: 0
Newbie Poster
oling is offline Offline
13 posts
since Nov 2008

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C Forum Timeline: Byte Reversal
Next Thread in C Forum Timeline: Functions with Pointers





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC