-3

Implement a program to multiply two numbers, with the mention that the first can have a maximum of 2048 digits, and the second number is less than 100. HINT: multiplication can be done using repeated additions.

Up to a certain point, the program works using long double, but when working with larger numbers, only INF is displayed. Any ideas?

  • long double gives you nowhere near that number of digits. – pm100 Nov 26 '22 at 22:38
  • 2
    When the question mentions 2000 digit this is out of range for double or any builtin variables in c (roughly 6k bits ). You should use arrays to store such long number. And you just write a function to add these arrays. – amirhm Nov 26 '22 at 22:41
  • For a real application, you'd use an [arbitrary precision arithmetic](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic) library such as [gmp](https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library). – Schwern Nov 26 '22 at 22:46
  • 1
    Write a program to multiply numbers the same way you learned to multiply multiple-digit numbers in elementary school. – Eric Postpischil Nov 26 '22 at 22:47

2 Answers2

0

Implement a program to multiply two numbers, with the mention that the first can have a maximum of 2048 digits, and the second number is less than 100.

OK. The nature of multiplication is that if a number with N bits is multiplied by a number with M bits, then the result will have up to N+M bits. In other words, you need to handle a result that has 2148 bits.

A long double could be anything (it's implementation dependent). Most likely (Windows or not 80x86) is that it's a synonym for double, but sometimes it might be larger (e.g. the 80-bit format described on this Wikipedia page ). The best you can realistically hope for is a dodgy estimate with lots of precision loss and not a correct result.

The worst case (the most likely case) is that the exponent isn't big enough either. E.g. for double the (unbiased) exponent has to be in the range −1022 to +1023 so attempting to shove a 2048 bit number in there will cause an overflow (an infinity).

What you're actually being asked to do is implement a program that uses "big integers". The idea would be to store the numbers as arrays of integers, like uint32_t result[2148/32];, so that you actually do have enough bits to get a correct result without precision loss or overflow problems.

With this in mind, you want a multiplication algorithm that can work with big integers. Note: I'd recommend something from that Wikipedia page's "Algorithms for multiplying by hand" section - there's faster/more advanced algorithms that are way too complicated for (what I assume is) a university assignment.

Also, the "HINT: multiplication can be done using repeated additions" is a red herring to distract you. It'd take literally days for a computer do the equivalent of a while(source2 != 0) { result += source1; source2--; } with large numbers.

Brendan
  • 35,656
  • 2
  • 39
  • 66
0

Here's a few hints.

Multiplying a 2048 digit string by a 100 digit string might yield a string with as many as 2148 digits. That's two high for any primitive C type. So you'll have to do all the math the hard way against "strings". So stay in the string space since your input will most likely be read in as much.

Let's say you are trying to multiple "123456" x "789".

That's equivalent to (123456 * (700 + 80 + 9)

Which is equivalent to to 123456 * 700 + 123456 * 80 + 123456 * 9

Which is equivalent to doing these steps:

result1 = Multiply 123456 by 7 and add two zeros at the end
result2 = Multiply 123456 by 8 and add one zero at the end
result3 = Multiply 123456 by 9

final result = result1+result2+result3

So all you need is a handful of primitives that can take a digit string of arbitrary length and do some math operations on it.

You just need these three functions:

// Returns a new string that is identical to s but with a specific number of
// zeros added to the end.  
// e.g. MultiplyByPowerOfTen("123", 3) returns "123000"
char* MultiplyByPowerOfTen(char* s, size_t zerosToAdd)
{
};

// Performs multiplication on the big integer represented by s
// by the specified digit
// e.g. Multiple("12345", 2) returns "24690"
char* Multiply(char* s, int digit) // where digit is between 0 and 9
{

};

// Performs addition on the big integers represented by s1 and s2
// e.g. Add("12345", "678") returns "13023"
char* Add(char* s1, char* s2)
{
    
};

Final hint. Any character at position i in your string can be converted to its integer equivalent like this:

int digit = s[i] - '0';

And any digit can be converted back to a printable char:

char c = '0' + digit

selbie
  • 100,020
  • 15
  • 103
  • 173