Trouble converting a decimal to a hexadecimal in its string form

Pages: 12
Hello everyone,

I've been given an assignment which tells me convert an input integer into a hexadecimal number in its string form. Also the teacher didn't permit me to use fast-integer-to-string functions, like sprintf for example. I then came up with a way on my own, but the program doesn't seem to work. Could anyone please tell me that what went wrong? Thanks in advance.

My algorithm :
+ Count the number one by one (until i > input)

+ When we get the remainder of zero (happens when (i % 16 == 0), the lowest digit level (lower than "dozen" level) will get a zero, and also trigger continually increasing the higher digit levels by one unit as long as their own digit values still happen to be greater than 15 (or 0xf) - they will also get a zero as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <sstream> // stringstream header

using namespace std;
int main()
{
    unsigned int i, j, input, pos;
    char hexa[10];
    const char *hexa_table = "0123456789ABCDEF";

    for(i = 0; i < sizeof(hexa); ++i) hexa[i] = 0;

    cout << "(Decimal to hexadecimal converter)" << endl;
    cout << "Input an integer you want hexalized : ";
    cin >> input; cout << endl;

    pos = sizeof(hexa);
    for(i = 0, j = 0; i <= input; ++i)
    {
        j = hexa[pos];
        if((hexa[pos] = hexa_table[i % 16]) == 0 && j == 'F')
        {
            do
            {
                hexa[pos--] = 0;
                if(hexa[pos] == 0) hexa[pos] = '0';    
            } while((hexa[pos] = strchr(hexa_table, hexa[pos])[0]) + 1 <= 'F');
            pos = sizeof(hexa);
        }
    }

    for (i = 0; i < sizeof(hexa); ++i)
    if(hexa[i] != 0)
    {
        hexa[i - 1] = 'x';
        hexa[i - 2] = '0';
        pos = i - 2; 
        break;
    }
    cout << "The hexadecimal number is : " << endl;

    cout << "  + My approach : " << &hexa[pos] << endl;

    cout << "  + Expected : 0x" << std::hex << input << std::dec << endl; // Will be removed when done 

    cin.get();
    return 0;
}


Edit : I updated my code a bit
Last edited on
closed account (48T7M4Gy)
.
Last edited on
You have numerous compiler errors.

Yeah, I know there are a lot of complier errors that I need to deal with. But really, I'm in a mess. Could you please point out some (major) errors or mistakes that I have made when writing my code and tell me how to fix them? Thanks.
closed account (48T7M4Gy)
.
Last edited on
Yeah, I know there are a lot of complier errors that I need to deal with. But really, I'm in a mess. Could you please point out some (major) errors or mistakes that I have made when writing my code and tell me how to fix them? Thanks.


I hate to be rude, but to be honest, you're asking an awful lot of the community when you show up with code that doesn't even compile from literally line 1, and even correcting that unleashes a wave of compiler errors once the preprocessor problems are sorted. I mean, you edited it to include, "I updated my code a bit" but you CLEARLY haven't even made the slightest bit of effort to actually test it. Not even a little bit! This code will (and does) fail - edited version or not - from the start.
Yeah, I know there are a lot of complier errors that I need to deal with. But really, I'm in a mess. Could you please point out some (major) errors or mistakes that I have made when writing my code and tell me how to fix them? Thanks.


Fine.

1.
1
2
#include <iostream>
#include <ioststream> 


2.
if((hexa[pos] = hexa_table[i % 16]) == 0 && j == 'F')

3.
while((hexa[pos] = strchr(hexa_table, hexa[pos])[0]) + 1 <= 'F');

4.
1
2
3
4
        hexa[i - 1] = 'x';
        hexa[i - 2] = '0';
        pos = i - 2; 
        break;
Half Life G Man, thank you. The code compiles now, but the program doesn't produce correct results.

(Decimal to hexadecimal converter)
Input an integer : 3820

The corresponding hexadecimal number is : C¦¦¦¦²²²²ÂD╩²¦¦♀


Why did it happen? Someone please help me...
closed account (E0p9LyTq)
You want to have a hex string, use a stringstream:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <sstream> // stringstream header
#include <string>

int main ()
{

   std::cout << "Enter a number you want hexalized: ";
   int x;
   std::cin >> x;
   std::cout << "\n";
   
   std::cout << "The number you entered was:\n"
             << std::hex << x << "\t" << std::dec << x << "\n";
   
   std::ostringstream foo; // create a stringstream object;
   foo << std::hex << x;
   std::cout << "Stringized hex: " << foo.str() << "\n";
   
   std::string foo2 = foo.str();
   
   std::cout << "\nString size: " << foo2.size() << "\n";
   
   for (unsigned int i = 0; i < foo2.size(); i++)
   {
      std::cout << foo2[i] << " ";
   }
   std::cout << "\n";
}

Enter a number you want hexalized: 3820

The number you entered was:
eec     3820
Stringized hex: eec

String size: 3
e e c
Last edited on
@FurryGuy
I appreciate your efforts but the teacher is putting a huge restriction on us. I must convert a decimal to a hexadecimal using some raw method, without using any shortcut or fast functions or libraries that he knows to get the job done. Of course, I may want to use these to check the correctness of my algorithm in the end. Code updated.

The result is still the same through :
(Decimal to hexadecimal converter)
Input an integer you want hexalized : 3820

The hexadecimal number is : 
  + My approach : C¦¦¦¦²²²²ÂD╩²¦¦♀
  + Expected : 0xeec
closed account (E0p9LyTq)
This is about as "brute force" method as I can get:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <string>
#include <cmath>
#include <vector>

int main ()
{
   std::cout << "Enter a number you want hexalized: ";
   int x;
   std::cin >> x;
   std::cout << "\n";
   
   // get the maximum size vector needed to hold the hex digits (in decimal form)
   int size_x = std::ceil(std::log10(x));
   
   // create the vector and initialize the elements to zero
   std::vector<int> foo(size_x, 0);

   int y = x;
   
   // get (and store) the individual digits in the vector
   for (int i = size_x - 1; i >= 0; i--)
   {
      int z = (y / (std::pow(16, i)));
      foo[i] = z;
      y -= (z * (std::pow(16, i)));  // subtract the digit
   }
   
   std::string hexed_string = "0x";
   std::string hex_string = "0123456789ABCDEF";
     
   // "convert" the individual decimal digits to hex and add to the string
   for (int i = size_x - 1; i >= 0; i--)
   {
      hexed_string += hex_string[foo[i]];
   }
   
   std::cout << "The hexed string is: " << hexed_string << "\n";
}


Enter a number you want hexalized: 3820

The hexed string is: 0x0EEC
Last edited on
FurryGuy, I have received your code. It works, but there is a drawback - it tends to create additional zero characters after the hexa sign ("0x") and before the actual value. As when I input bigger values, more redundant zero characters may be created in a output hexa string. Which might not look good if I showed it to my teacher right now. Not that it is a problem through, because I can fix it easily by this :

1
2
3
4
5
6
7
8
   // "Convert" the individual decimal digits to hex and add to the string

   int i = size_x - 1;
   for (i = i; i > 0; i--) if(foo[i] != 0) break;
   for (i = i; i >= 0; i--)
   {
      hexed_string += hex_string[foo[i]];
   }


Thank you so much for your code. I will use it as a last resort if I somehow can't manage to finish my own in time. That means that I still have time left and I am awaiting some helpful opinions and comments regarding my own code (and its algorithm), and avoid cheating when unnecessary. Your algorithm & code may look standard and more professional, but I think mine is a little bit faster than yours. Only thing I really want to know is that why my code doesn't work properly as expected, and if there is an explanation for this, the more the better.

Thanks.
closed account (E0p9LyTq)
I never said it was the BEST solution, it was merely a "brute force" get-it-working code slam.

You used it as a base to improve the code, which is as it should be. You learned something. :)

Not every decimal number has a leading zero when converting to hex with my method, though.

One slight problem with what you did. What if you have embedded between non-zero hex digits a hex digit of zero? You would discard that valid digit.

Enter 258. You will get 0x102. No leading zero, with a valid zero hex digit.
Last edited on
closed account (48T7M4Gy)
.
Last edited on
Warning : (tl;dr)

1.
1
2
3
4
5
pos = sizeof(hexa); 

// (. . . . .)

cout << "My approach : " << &hexa[pos] << endl;


Firstly, the element hexa[10] does not exist. Assuming it is still somehow valid to access the eleventh element of hexa (it happens throughout your program), the program simply produces junk because hexa[11] is not set to zero (but hexa[11] is even more invalid)

pos does not ever change throughout the program; pos is always 10. I suppose you write your hex digits from the end (of the output string) to the beginning. Since there may be elements that are still unused (or null elements) in the hexa string after the program finishes its algorithm, you attempt to locate the "meat" of it by searching for the first valid digit character in hexa starting from the beginning. . .


1
2
3
4
5
6
7
8
for (i = 0; i < sizeof(hexa); ++i)
if(hexa[i] != 0)
{
    hexa[i - 1] = 'x';
    hexa[i - 2] = '0';
    pos = i - 2; 
    break;
}


You can assume it is the last outpost that validates the final value of (pos) and the fate of your program depends on it. However, it just doesn't work and never lives up to your expectations, the if condition is never fulfilled because your program didn't detect a single valid digit character in it. True, there is one (and the only) element in the hexa string that is constantly modified during the execution of your algorithm (it is the invalid one or hexa[10]), though your program will never reach it due to this for (i = 0; i < sizeof(hexa); ++i).

Solution : Replace pos = sizeof(hexa); with pos = sizeof(hexa) - 1;


(To be continued. . .)
2.

Actually you may see the last digit of (0xEEC) in
C¦¦¦¦²²²²ÂD╩²¦¦♀
(now becomes
0xC¦¦¦¦²²²²ÂD╩²¦¦♀
). It means that your algorithm is able to handle correctly a single digit, but not enough. Though, it can be easily noticed that one part of your algorithm (or perhaps the most vital one) is never reached, thus preventing the program from reaching higher hex digit levels. And your program stucks. This problem (mistake) may be a bit tricky to be noticed by inexperienced programmers, and I'm sure you will never forget this ever again for life after reading this :


1
2
if((hexa[pos] = hexa_table[i % 16]) == 0 && j == 'F')
if((hexa[pos] = hexa_table[i % 16]) == '0' && j == 'F')


The remainder used in the forementioned access operation always changes according to i % 16, and with hexa_table[i % 16] this may result in any value in hexa_table ranging from '0' -> 'F'. Sadly, (0) is not ('0'), and (0) does not even exist in hexa_table since the remainder only ranges from (0 -> 15). As a result, you just happened to create an impossible "if" condition and you can pretty much say anything which can be found in this mentioning "if" block is considered "death", unfortunately.


Now you finally get your most vital "if" part to work, and no - you are instantly facing another problem yet again. Allow me to apologise to you beforehand - I did make a "subtle" mistake when correcting one of your complier errors. While it might not pose much of a threat, there is also another one that is even more deadly once after all the efforts your program just barely managed to reach it. That is, your program quickly crashes when pos happens to drop below zero - and since (pos) is an unsigned, once it becomes "negative" - just a single access attempt with that "ridiculous" (pos) index is even more than lethal. So...


1
2
3
4
5
do
{
     hexa[pos--] = 0;
     if(hexa[pos] == 0) hexa[pos] = '0';    
} while((hexa[pos] = strchr(hexa_table, hexa[pos])[0]) + 1 <=  'F');



This "<=" part is the real curpit that makes your program loop forever. Assuming (pos) keeps decreasing over time, the element in hexa which (pos) "points to" is always first filled with 'zero' ('0') (the element was always null because it was never used), and soon after the element will be compared with (<= 'F'), which is always true (even with and without "+ 1" in the first place).

Solution : Replace (<=) with (>)


About this "+ 1" part, it should be put inside the assignment expression so that the higher hex digit levels may get a chance to increase. Thus, putting that "+ 1" outside making this totally meaningless - (hexa[pos] = strchr(hexa_table, hexa[pos])[0])


And finally, you just happened to make the same mistake again - hexa[pos--] = 0;. This should be : hexa[pos--] = '0';


(To be continued. . .)
3.

After fixing that many errors, you will be receiving
0xEEC¦¦¦¦²²²²ÂD╩²¦¦♀
as your very first present. But things didn't just end there - you will be still receiving some weird junk characters - much to your very surprise. Why? Because hexa[9] - the last valid element of the string (hexa) is supposed to be the null character that marks the end of string - it has been replaced to do other things for good. Applying this code should fix the problem :


pos = sizeof(hexa) - 2;


Since an element is alreadly reserved for that purpose, there are only seven slots remaining for storing hex digits - not enough since a very large hex value is usually 8-digit long. Before that, I'd like to congratulate you on being able to make this far. And the last thing that you need to do is this :

char hexa[11];


Hope this helps.
closed account (48T7M4Gy)
.
Last edited on
"Your algorithm & code may look standard and more professional, but I think mine is a little bit faster than yours."


I don't get this. Your code wasn't faster because at the time it didn't even solve the intended problem. As was quoted by Gerald Weinberg:

"If it doesn't have to produce correct results, I can make it arbitrarily fast."


You're awfully critical of the free work others do for you. Perhaps since this is clearly a school assignment with restrictions, you should contact your instructor?
> This has become so excruciatingly painful.
¿Painful for who?
By the way
Please enter an integer: 0
Decimal 0 is 0x



This thread should have stopped at «I will use it if I can't manage to finish my own in time.»
@Half Life G Man
How long did you spend writing "these"? :O
Pages: 12