Click to See Complete Forum and Search --> : Help Understanding a piece of Code


goatslayer
December 6th, 2007, 06:49 AM
There is this neat piece of code on the next for converting a decimal value into hex, I can't quite figure out how it works, I was wondering if anyone could help.


#include <iostream>
using namespace std;

int main() {
int n;
while (cin >> n) {
cout << "decimal: " << n << endl;


cout << "size of int: " << sizeof(int) << endl;

//--- Print hex with leading zeros
cout << "hex : ";
for (int i=2*sizeof(int) - 1; i>=0; i--) {
cout << "0123456789ABCDEF"[((n >> i*4) & 0xF)];
}
cout << endl << endl;
}
return 0;
}


My bitwise is a little flaky to say the least, but I'm eager to learn it. I was hoping some light shed on this might help me.

The original source is Convert to Hex (http://www.fredosaurus.com/notes-cpp/expressions/bitopsex.html/)

PredicateNormative
December 6th, 2007, 07:43 AM
Hi goatslayer. So as to not spoil your learning fun, here is a link to a nice bitwise operator explanation:

http://www.phim.unibe.ch/comp_doc/c_manual/C/CONCEPT/bitwise.html

This should help you figure it out. :)

Edit:

Also here is a binary-hex conversion table:

http://www.dewassoc.com/support/msdos/decimal_hexadecimal.htm

Ignore the '0x' in front of the hex numbers you compare to when using this table. For example 0xF is 'f' on the hex conversion table, and 0xFF is 'ff'.

Hnefi
December 6th, 2007, 07:48 AM
Why not replace half of that code with this much simpler version?
cout << "hex :" << hex << end;

goatslayer
December 6th, 2007, 08:13 AM
Thanks PredicateNormative, I'll have a good look at that, I think the basics of the bitwise I have down so I might be back, as I think the main source of my problem is:

"0123456789ABCDEF"[((n >> i*4) & 0xF)];

Is that some sort of cast? with the hex characters first?

Hnefi - I might not get the bitwise fully, but I believe this code allows you to store the value in the loop in a char array, or string or whatnot first. - cout << hex only formats on console output if I am not mistaken?

And the alternative:

itoa(int, string, base) - is non standard and not supported by all compilers.

EDIT: the point being, much more useful.

GNiewerth
December 6th, 2007, 08:25 AM
Hint:
There´s no cast involved, just a local anonymous char array.

Lindley
December 6th, 2007, 08:26 AM
I think that expression is indexing into a literal string. I didn't know that was possible, but I suppose it would be.

goatslayer
December 6th, 2007, 08:31 AM
GNiewerth, Lindley: Thank you. That along with PredicativeNormative's comments, should just about help me fill in the blanks if I'm not mistaken. Excellent work.

jwbarton
December 6th, 2007, 08:49 AM
It is a little clearer if you change it to the following:


inline char HexDigit( int value )
{
return "0123456789ABCDEF"[value];
}

...

cout << HexDigit(((n >> i*4) & 0xF));


Note that the pointer[index] in C++ is equivalent to *(pointer+index), so either of the following would also work:


inline char HexDigit( int value )
{
return value["0123456789ABCDEF"];
}


or


inline char HexDigit( int value )
{
return *("0123456789ABCDEF"+value);
}

PredicateNormative
December 6th, 2007, 08:50 AM
Hnefi - I might not get the bitwise fully, but I believe this code allows you to store the value in the loop in a char array, or string or whatnot first. - cout << hex only formats on console output if I am not mistaken?

Hnefi's solution is the simplest, and if you want to pipe the solution to a string first then you can slightly modify it to use ostringstream instead of cout:


#include <iostream>
#include <string>
#include <sstream>

int main()
{
int num = 255;
std::ostringstream os;

//cout
std::cout << std::hex << num << std::endl;

//ostringstream equivalent
os << std::hex << num << std::endl;


std::string myString = os.str();
std::cout << myString.c_str() << std::endl;
}