Large nums

The task is the following: we have two char arrays that can be with diff sizes that represent big nums and we have to multiply them, to do the addition, the division, compare them etc. I have written the addition but it doesnt work, what is the problem?

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
  const int MAX = 8172;

void readArr(char arr1[], size_t size)
{
	for (size_t i = 0; i < size; i++)
	{
		cin >> arr1[i];
	}
}

void printArr(char arr1[], size_t size)
{
	for (size_t i = 0; i < size; i++)
	{
		cout << arr1[i];
	}
}

void addition(char arr1[], char arr2[], size_t size1, size_t size2)
{
	char arrResult[MAX];
	if (size1 > size2)
	{
		for (size_t i = size1 - 1; i > 0; i--)
		{
			int sum = 0;
			int num1 = arr1[i] - '0';
			int num2 = arr2[i] - '0';
			sum = num1+num2;
			if (sum > 9)
			{
				arrResult[i] += sum % 10;
				arrResult[i+1] += sum / 10;
			}
                        else
			{
				arrResult[i] += sum;
			}
		}
	}
	else
	{
		for (size_t i = size2 - 1; i > 0; i--)
		{

		}
	}

	printArr(arrResult, size1);
}

int main() {
	char arr1[MAX];
	char arr2[MAX];

	cout << "Enter the size of the first num: " << endl;
	size_t size1 = 0;
	cin >> size1;
	cout << "Enter the first num: " << endl;
	readArr(arr1, size1);
	
	cout << "Enter the size of the second num: " << endl;
	size_t size2 = 0;
	cin >> size2;
	cout << "Enter the second num: " << endl;
	readArr(arr2, size2);

        cout << "The addition of the two nums: " << endl;
	addition(arr1, arr2, size1, size2);
	cout << endl;
	cout << endl;

return 0;
}


Alse we cant work with dynamic memory for this task, cant use vectors and other data structures
Last edited on
You probably mean to initialize your arrResult[MAX] to something. Perhaps zeroes (the character '0', not the null character)?
1
2
3
4
for (size_t i = 0; i < MAX; i++)
{
    arrResult[i] = '0';
}

(In your printing code, you could have it not print leading zeroes.)

Note that carries can propagate,
   999
+    1
 1 000 


But the real problem is that your numbers are not aligned.

Let's say your first number is 123.
It gets filled in as { '1', '2', '3', .... }.

And then your second number is 45.
It gets filled in as { '4', '5', ... }.

Your code will then attempt to add '3' with whatever the third character of your second number is, but you want it to add '3' with 5.

So the first thing, would to make sure your numbers are aligned correctly before trying to add them:
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
#include <iostream>
#include <algorithm>
using namespace std;
 
const int MAX = 100;

void readArr(char arr1[], size_t size)
{
	for (size_t i = MAX - size; i < MAX; i++)
	{
		cin >> arr1[i];
	}
}

void printArr(char arr1[], size_t size)
{
	for (size_t i = MAX - size; i < MAX; i++)
	{
		cout << arr1[i];
	}
	cout << '\n';
}

int main() {
	char arr1[MAX];
	char arr2[MAX];
	
	for (size_t i = 0; i < MAX; i++)
	{
	    arr1[i] = '0';
	    arr2[i] = '0';
	}

	cout << "Enter the size of the first num: ";
	size_t size1 = 0;
	cin >> size1;
	cout << "Enter the first num: ";
	readArr(arr1, size1);
	
	cout << "Enter the size of the second num: ";
	size_t size2 = 0;
	cin >> size2;
	cout << "Enter the second num: ";
	readArr(arr2, size2);
	
	size_t largest_size = std::max(size1, size2);
	
	printArr(arr1, largest_size);
	printArr(arr2, largest_size);

    return 0;
}

Enter the size of the first num: 3                           
Enter the first num: 123                                                        
Enter the size of the second num: 2                                                   
Enter the second num: 45                                                                      
123                                                                                    
045                                                                           
Enter the size of the first num: 5                                                            
Enter the first num: 12345                                                            
Enter the size of the second num: 7                                               
Enter the second num: 1234567                                             
0012345                                                                             
1234567


With this setup, your_arr[MAX-1] will always be the least-significant digit.
your_arr[MAX-1 - 1] is then the tens place.
your_arr[MAX-1 - 2] is the hundreds place, etc.

You could have the larger number start at index 0, but you don't know what the larger number is until you've entered both, so you'd need to shift the numbers after the fact. And, if the larger number starts at index 0, then you can't do anything about 998 + 2 becoming 1000, because the 1 would drop off.
Last edited on
Thanks that helped me a lot.
Last edited on
Do you remember learning multiple-digit multiplication in ~4th grade? The one's digit of the bottom number multiplied against each of the digits in the upper number, adding in a carry from the previous multiplication. Then then10's digit does the same, but the results are shifted one digit over to the left. When all of the multiplications are done, add the sub-results together to get the final answer.

Do it manually a few time to remember how to do it. Then do these steps in your code.

It's not really that hard if you do it step by step. Refreshing yourself on 4th-grade math and understanding why it's done that way is the hardest part.
if you have some math background you can see how the same concept as that 4th grade math works on larger groups of bytes. EG you can let the cpu do a 32 bit multiply which will fit into a 64 bit result. you can take the result of that to have your result (32 bit) and carry (32 bit). That is where it gets a little funky; 32bit * 32bit + 32bit can overflow, so you need to handle that case OR use less bits for the math -- both approaches work. Its a lot faster than digit by digit, and its much, much better than doing it as text ('1', '2', etc). None of that is important right now; if you really need an industrial bigint, you can get a library off the web, but it may help you as you think about things. This is looking at the problem via logarithms from a sideways angle... eg, a base of 2^25 or whatever fits correctly approach instead of base 10 or base 2 or whatever.
Last edited on
Topic archived. No new replies allowed.