Problem with hexadecimals addition implementation

Hello, I'm fairly new to programming and taking the introductory course for C++, and I'm having problems with a particular problem.

The problem is that I need to add two hexadecimals together, which i store in two arrays (a[] and b[]) of type char up to size of 10, and output the result of their addition as another array of type char(called c[]). If the addition of arrays results in a hexadecimal greater than 10 digits, I'm asked to output "Addition Overflow" and do nothing more.

My problem is inside the function I wrote that adds both arrays. Prior to this function call, I wrote a function that fills up the array with input from the user, and after that I filled the remaining elements of the array with '\0' (empty).

Before I post the code, here is the algorithm I designed for the function that adds the hexadecimals:
1. declare Initialize a variable called sum to 0, which is the result of adding the characters at index 'i' of arrays a[] and b[].
2. Use the isdigit and isalpha functions to check whether the character at index i (for both arrays) is a digit or a letter of the alphabet. Depending on which case it is, I use a subtraction operation to get the numerical value of the character and store that in sum. I tested this function separately in a driver program and it seems to have worked fine, so I don't believe this is the problem.
3. Once I have the values of sum, I used if-else statements to check their numerical value and assign the correct character belonging to it, to the array c at index j, which was declared and initialized to 0 before the loop started, and is incremented by one at the end of the loop.

If the number happens to be greater than 15, and less than 32, then I wrote code to subtract 16 from the total of sum, and repeat the same if-else statements to assign the character values to c[j].

The reason I do that separately is because if there is a value greater than 15, there is a "carry over" in the addition, so next time the loop iterates, sum will start at "1" instead of 0.

4. The loop will end when either the maximum size has been reached, or when both array values at index i are '\0' (in which case it will break).

My problem: When I compile and run the program, the output for the addition seems to be garbage values each time. I'm not entirely sure as to why that is, other than my biggest lead being something wrong in the loop specifically (as i have tested every other function in the program separately and they seemed to have worked fine.)

If anybody could give me some tips, advice, or point out the issue, I would be incredibly thankful. I just want to be pointed in the right direction so I can solve this problem.

Thanks!

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  void hexadecimal_addition(char a[], char b[], char c[], int size)
{
	int sum = 0;
	int j = 0;

	for(int i = size - 1, j = 0; (i >= 0); i--)
	{
		if(a[i] == '\0' && b[i] == '\0')
			break;
		if(isdigit(a[i]))
			sum += (a[i] - '0');
		if(isalpha(a[i]))
			sum += (a[i] - 'A') + 10; 
		if(a[i] == '\0')
			sum += 0;
		if(isdigit(b[i]))
			sum += (b[i] - '0');
		if(isalpha(b[i]))
			sum += (b[i] - 'A') + 10;
		if(b[i] == '\0')
			sum += 0;

		//now the array will be filled
		if(sum < 16)
		{
			if(sum == 0)
				c[j] = '0';
			if(sum == 1)
				c[j] = '1';
			if(sum == 2)
				c[j] = '2';
			if(sum == 3)
				c[j] = '3';
			if(sum == 4)
				c[j] = '4';
			if(sum == 5)
				c[j] = '5';
			if(sum == 6)
				c[j] = '6';
			if(sum == 7)
				c[j] = '7';
			if(sum == 8)
				c[j] = '8';
			if(sum == 9)
				c[j] = '9';
			if(sum == 10)
				c[j] = 'A';
			if(sum == 11)
				c[j] = 'B';
			if(sum == 12)
				c[j] = 'C';
			if(sum == 13)
				c[j] = 'D';
			if(sum == 14)
				c[j] = 'E';
			if(sum == 15)
				c[j] = 'F';

			sum = 0;
		}
		else if(15 < sum && sum < 32)
		{
			sum -= 16;

			if(sum == 0)
				c[j] = '0';
			if(sum == 1)
				c[j] = '1';
			if(sum == 2)
				c[j] = '2';
			if(sum == 3)
				c[j] = '3';
			if(sum == 4)
				c[j] = '4';
			if(sum == 5)
				c[j] = '5';
			if(sum == 6)
				c[j] = '6';
			if(sum == 7)
				c[j] = '7';
			if(sum == 8)
				c[j] = '8';
			if(sum == 9)
				c[j] = '9';
			if(sum == 10)
				c[j] = 'A';
			if(sum == 11)
				c[j] = 'B';
			if(sum == 12)
				c[j] = 'C';
			if(sum == 13)
				c[j] = 'D';
			if(sum == 14)
				c[j] = 'E';
			if(sum == 15)
				c[j] = 'F';

			sum = 1;
		}

		else // somehow got a wrong number in sum 
			cout << "Error in sum\n"; 
		j++;
	}

	cout << "Hexadecimal result: ";
	for(int i = 0; i < size; i++)
		cout << c[i];
	cout << endl;

	if(sum == 1)
	{
		cout << "Addition Overflow\n";
		exit(1);
	}
	return;
}


I know the code is a little messy, but I'm still fairly new and only using the tools that we've seen in class so far. But if any of you have suggestions on how to make the code nicer, feel free to point it out as well, if you want to.
the computer speaks neither base 10 nor base 16. It speaks base 2.
understanding that, you can do this work as numbers the whole way...
that is, you can read a value from the user in hex, as a text string, convert that to numeric format, do the math, and write out the answer in base 16 without all this work. I think you can even read the input in base 16 directly but standard practice is to read everything as strings to allow data validity checks. The whole thing could be done in about 4 lines of code.

that aside (the above does not teach you anything except maybe the "work smarter" principle) you can also do this with lookup tables much more efficiently.

eg:
string lkp[] = {"0", "1", "2", ...skip ... "F"}; //16 values for the hex digits
then you can do this:
c[j] = lkp[sum][0];
to replace the ENTIRE block of statements doing this:
if(sum == 10)
c[j] = 'A';

because if sum is 10, it goes to lkp[10] and fetches "A" for you.

And I can't stop here without saying that you have done a nice job here. You had a design and an idea and you put it together and got it working. That is huge. Just because there are better ways does not in any way invalidate that.

I don't see the problem right off the top. I will look at it later, I am at work and can't dig into it right now. Or one of the other folks here might see it shortly.

hex is nice because once you have 1/2 a byte (16 values) you can string together the pieces to do any sized number with just a little more work.
Last edited on
Thanks so much for the help! Don't worry about not being able to help right now, this homework isn't due yet so I can wait a little, haha

Quick question: Can I do this part separately (i.e. just add it into my existing code):
string lkp[] = {"0", "1", "2", ...skip ... "F"}; //16 values for the hex digits
then you can do this:
c[j] = lkp[sum][0];

Except changing the type from string to char? I've never heard of lookup tables until now, so I'm just wondering! It seems like it would shorten my source code by a lot.

Thanks so much again for your time!
yes, you can do that now and it should have no effect. However if your BUG is related to SUM being incorrect, it MAY crash here, going out of bounds in the lookup table. If that happens, it will help find the issue anyway!

you can do it with char ...

char lkp[] = "0123456789ABCDEF";
replace with
c[j] = lkp[sum];

a lookup table is a *concept*. What this is, is an array of characters being used as a lookup table. A lookup table is not a "C++" thing.

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
51
52
53
54
55

void hexadecimal_addition(char a[], char b[], char c[], int size)
{
        char lkp[]  = "0123456789ABCDEF";
	int sum = 0;
	int j = 0;

	for(int i = size - 1, j = 0; (i >= 0); i--)
	{
		if(a[i] == '\0' && b[i] == '\0')
			break;
		if(isdigit(a[i]))
			sum += (a[i] - '0');
		if(isalpha(a[i]))
			sum += (a[i] - 'A') + 10; 
		if(a[i] == '\0')
			sum += 0;
		if(isdigit(b[i]))
			sum += (b[i] - '0');
		if(isalpha(b[i]))
			sum += (b[i] - 'A') + 10;
		if(b[i] == '\0')
			sum += 0;

		//now the array will be filled
		if(sum < 16)
		{
                       c[j] = lkp[sum];
			sum = 0;
		}
		else if(15 < sum && sum < 32)
		{
			sum -= 16;
                        c[j] = lkp[sum];
			sum = 1;
		}

		else // somehow got a wrong number in sum 
			cout << "Error in sum\n"; 
		j++;
	}

	cout << "Hexadecimal result: ";
	for(int i = 0; i < size; i++)
		cout << c[i];
	cout << endl;

	if(sum == 1)
	{
		cout << "Addition Overflow\n";
		exit(1);
	}
	return;
}
Last edited on
A couple of comments on your program:

Line 1: It's not clear whether size represents the size of a and/or b or the max size of c.

Line 13,19: You're assuming the hex string is upper case. What if lower case characters are present?

There's no editing of the input hex strings. What if the input strings are not valid.
Last edited on
@jonnin: Thanks! I get it now. The way I did it was that I implemented a map. Also, when the sum goes "out of bounds" what I did was add an if statement where if sum is greatee than 15, to subtract 16 to bring it back into range, so I shouldn't have any problems, right?

@AbstractionAnon: I did not add all of the source code I have, sorry for that, but all of the hexadecimal arrays have a max size of 10. So size is the max size, which is 10.

Also I used the toupper function in my program to automatically convert all characters the user enters. It's just in another function that I didn't include either, sorry again for the confusion.
UPDATE: I finally figured out what I was doing wrong.

I was trying to read the arrays front to back, and because I had filled the remaining array elements with '\0' the condition on line 12 was *always* true thus it would break. Meaning that I would get garbage values since I had never filled them in the first place. I used output lines to keep track of sum to see if it was (somehow) going out of bounds (thanks jonnin for making me wonder this) and saw that sum would never output.

I changed my approach by reversing the arrays and adding them in reverse order. That meant I got the result in reverse but i would just simply need to reverse that result and it worked!!

Thanks so much jonnin for the help and for the nice comment about being able to put together a design and idea, meant a lot!

and thus was born the great endian conundrum :(

You will go far, I predict a career at intel...

(google endian if you miss the jokes here, I am just playing).


Topic archived. No new replies allowed.