1
    #include<stdio.h>
    int count_num_string(char*);
    void str_reverse(char*, int);
    void mul_and_sum(char*, char*, int, int);

    int main()
    {
         char str1[50], str2[50];
         char sum_str[100] = "0";
         printf("Enter num string1 : ");
         scanf("%s",str1);

         printf("Enter num string2 : ");
         scanf("%s", str2);
         int len1, len2, l, m;
         len1 = count_num_string(str1);
         len2 = count_num_string(str2);

         str_reverse(str1, len1);
         str_reverse(str2, len2);

         mul_and_sum(str1, str2, len1, len2);
         printf("str1 = '%s'\n", sum_str);
         //printf("str2 = %s\n", str2);


    }

    int count_num_string(char* str)
    {
       int i = 0;
       while(str[i] != 0)
          i++;
       return i;
    }
     void str_reverse(char *str, int len)
    {
       int count, i;
       char *begin_ptr, *end_ptr, ch;
       begin_ptr = str;
       end_ptr = str +len -1;
       if(len%2 == 0)
        count = len/2;
      else if(len%2 != 0)
        count = (len-1)/2;
      for(i = 0;i<count;i++){
        ch = *end_ptr;
        *end_ptr = *begin_ptr;
        *begin_ptr = ch;
        begin_ptr++;
        end_ptr--;
     }

   }


    void mul_and_sum(char* str1, char* str2, int len1, int len2)
    {
    char sum_str[100] = "0";
    int bigger, smaller,m, add_zero,j,k,adjuster, sum;
    int carry = 0, carry1 = 0, carry2 = 0;
    char mulstr[100];
    if(len1>=len2){
        bigger = len1;
        smaller = len2;
        for(j= 0;j<smaller;j++){
            m=0;
            for(k = 0; k<bigger; k++){
                mulstr[m] = (((str1[k]-48)*(str2[j]-48)) + carry)%10;
                carry = (((str1[k]-48)*(str2[j]-48)) + carry)/10;
                printf("multstr[%d] = %d, carry = %d\n", m,mulstr[m],carry);
                m++;
            }
            mulstr[m] = carry;
            printf("multstr[%d] = %d\n", m,mulstr[m]);

            if(j == 0){ //m+1 = elements+carry//add later m+1
                **for(sum = 0; sum<m+1; sum++){
                    sum_str[sum] = (((sum_str[sum]-48)+(mulstr[sum]-48))+carry1)%10;
                    carry1 = (((sum_str[sum]-48)+(mulstr[sum]-48))+carry1)/10;

                    printf("sumstr[%d] = %d, carry1 = %d\n", sum,mulstr[sum],carry1);
     **
                }
                printf("carry = %d", carry1);
                sum_str[sum] = carry1-48;
                printf("sumstr[%d] = %d\n", sum,mulstr[sum]);
                sum++;
                 printf("hello sumstr[%d] = %d\n", sum,mulstr[sum]);
               // sum_str[sum] = '\0';

            }
            if(j>0){

                int shifter, size, zero_adder,add;
                adjuster = m+j;
                printf("m = %d, adjuter = %d,j = %d\n", m, adjuster,j);
                size = j;
                for(shifter = adjuster;shifter>=size;shifter--)
                {

                    mulstr[shifter]= mulstr[shifter-size];
                    printf("multstr[%d] = %d\n", shifter,mulstr[shifter]);
                }

                for(zero_adder = 0;zero_adder<size;zero_adder++){
                    mulstr[zero_adder] = 0;
                    printf("multstr[%d] = %d\n", zero_adder,mulstr[zero_adder]);
                }

                printf("one done\n");
                for(add = 0; add<=adjuster; add++){
                    printf("sumstr[%d] = %d, multstr[%d] = %d\n", add, sum_str[add], add, mulstr[add]);
                    sum_str[add] = (sum_str[add]+mulstr[add]+carry2)%10;
                    carry2 = (sum_str[add]+mulstr[add]+carry2)/10;
                   //printf("sumstr[%d] = %d\n", add,sum_str[add]);

                }
                sum_str[sum] = carry2;
                sum++;
                sum_str[sum] = '\0';



           //str_reverse(sum_str, add);
            }

        }
    }
   }

The following is the output:

    Enter num string1 : 1234
    Enter num string2 : 123
    multstr[0] = 2, carry = 1
    multstr[1] = 0, carry = 1
    multstr[2] = 7, carry = 0
    multstr[3] = 3, carry = 0
    multstr[4] = 0
    sumstr[0] = 2, **carry1** = -10
    sumstr[1] = 0, **carry1** = -11
    sumstr[2] = 7, **carry1** = -10
    sumstr[3] = 3, **carry1** = -10
    sumstr[4] = 0, **carry1** = -11
    **carry** = -11sumstr[5] = 0
    hello sumstr[6] = 0
    multstr[0] = 8, carry = 0
    multstr[1] = 6, carry = 0
    multstr[2] = 4, carry = 0
    multstr[3] = 2, carry = 0
    multstr[4] = 0
    m = 4, adjuter = 5,j = 1
    multstr[5] = 0
    multstr[4] = 2
    multstr[3] = 4
    multstr[2] = 6
    multstr[1] = 8
    multstr[0] = 0
    one done
    **sumstr[0] = -6**, multstr[0] = 0
    **sumstr[1] = -6**, multstr[1] = 8
    **sumstr[2] = 0**, multstr[2] = 6
    **sumstr[3] = -3**, multstr[3] = 4
    **sumstr[4] = -6**, multstr[4] = 2
    **sumstr[5] = -59**, multstr[5] = 0
    multstr[0] = 4, carry = 0
    multstr[1] = 3, carry = 0
    multstr[2] = 2, carry = 0
    multstr[3] = 1, carry = 0
    multstr[4] = 0
    m = 4, adjuter = 6,j = 2
    multstr[6] = 0
    multstr[5] = 1
    multstr[4] = 2
    multstr[3] = 3
    multstr[2] = 4
    multstr[0] = 0
    multstr[1] = 0
    one done
    sumstr[0] = -6, multstr[0] = 0
    sumstr[1] = 2, multstr[1] = 0
    sumstr[2] = 7, multstr[2] = 4
    sumstr[3] = 2, multstr[3] = 3
    sumstr[4] = -4, multstr[4] = 2
    sumstr[5] = -9, multstr[5] = 1
    sumstr[6] = 0, multstr[6] = 0
    str1 = '0'

I am trying to multiply two 50-digit numbers, without using in-built functions. I highlighted the part of the code, where it is giving error/garbage value for carry1. Also, the sum of strings (sum_str and mulstr) is not correct. Can someone please explain why I am not getting the correct value of carry1 and sum_str?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    The function `mul_and_sum`'s variable `sum_str` is a different variable from `main`'s `sum_str`. The function never gets to know about the one in `main`. It takes some input arguments but does not provide an answer. – Weather Vane Jul 18 '23 at 19:26
  • 3
    Aside: please don't use asterisks in the code to highlight problem areas: they make malformed code. Use properly formatted C comments so that the code will compile. – Weather Vane Jul 18 '23 at 19:42
  • Note that it's extraordinarily wasteful in both storage and computation to store each digit as one byte with base-10. If you instead use base-256 you can utilize all the bits. Or even use a wider native type like `uint32_t`. Also highly recommend you do _not_ use magic constants like `48` for character arithmetic. That makes a non-portable assumption about the underlying character set and also relies on special knowledge when working with the code. It eats unnecessary brain cycles to read the code's intent. Use the character literal `'0'` instead. – paddy Jul 18 '23 at 21:41
  • @paddy yes but you have the overhead of packing first and unpacking last. By working with 10 possible multipliers, an efficient solution can cache each of the 10 possible partial products, only needing to align and sum one into the product if it's already cached. – Weather Vane Jul 18 '23 at 22:10

1 Answers1

1

At least these problems:

1 too small

str1[50] is 1 too small to store a 50 digits string. Make room for the null character.

2 different sum_str

OP assumes sum_str in main() and mul_and_sum() are the same object. They are 2 different objects. @Weather Vane

Instead pass into mul_and_sum() the place to store the product.

int main() {
    char str1[50+1], str2[50+1];
    char sum_str[100+1] = "0";
    // ...
    // mul_and_sum(str1, str2, len1, len2);
    mul_and_sum(sum_str, str1, str2, len1, len2);
    printf("str1 = '%s'\n", sum_str);

void mul_and_sum(char *sum_str, char* str1, char* str2, int len1, int len2) {
    // char sum_str[100] = "0";

Avoid buffer overflow

Do not use scanf("%s",str1); without a width.

char str1[50+1];
scanf("%50s",str1);

Good code checks scanf() return value.

if (scanf("%50s",str1) != 1) {
  fprintf(stderr, "Failed to read input.\n");
  return -1;
}

Tip: Use character constants

Why 48? '0' is more clear.

//str1[k]-48
str1[k]-'0'
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Nit: should not return a negative value to the shell `:)` (maybe `#include ` and `exit EXIT_FAILURE;` and let the compiler worry about it) – David C. Rankin Jul 18 '23 at 21:45
  • @DavidC.Rankin Why not negative? – chux - Reinstate Monica Jul 19 '23 at 00:51
  • POSIX reserves 8-bit values other than `0` or `1` for various error codes. Returning a negative value is a can-of-worms on how the shell will interpret that as an 8-bit value. I'll dig up a cite. [Return negative value in main in C](https://stackoverflow.com/q/22078712/3422102) - this isn't the one I'm thinking of, Leffler had a better write up that I'll find. – David C. Rankin Jul 19 '23 at 02:35
  • [POSIX OpenGroup - return](https://pubs.opengroup.org/onlinepubs/009695399/utilities/return.html) and [POSIX OpenGroup - exit - discussion](https://pubs.opengroup.org/onlinepubs/009695399/utilities/exit.html#tag_04_47_15) are the POSIX standard cites I was referring to. – David C. Rankin Jul 19 '23 at 02:41
  • @DavidC.Rankin OK, so not a C standard concern. – chux - Reinstate Monica Jul 19 '23 at 02:47
  • Correct -- it's the shell the exiting C (or any type) program is returning to that matters. The C standard does provide the `EXIT_SUCCESS` and `EXIT_FAILURE` (`0` and `1`) macros to comply with the shell requirements (2nd OpenGroup link re: `exit` above). That was the primary reason for the `"Nit"` prefixing above -- but it is something to be mindful of. – David C. Rankin Jul 19 '23 at 07:19
  • @DavidC.Rankin Note: "EXIT_SUCCESS and EXIT_FAILURE (0 and 1)" --> They may be other than 0, 1. e.g. "If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned." C23dr § 7.24.4.4 5 – chux - Reinstate Monica Jul 19 '23 at 16:51
  • Mine reads *"which expand to integer constant expressions that can be used as the argument to the exit function to return unsuccessful or successful termination status, respectively, to the host environment;"* which has been unchanged since at least the C99 standard C99 §7.20. You have a good point on the implementation defined aspect of it, which like computers that don't use twos-compliment, may use something other than `0` and `1` as the return values. (those *rare as hen's-teeth boxes* `:)` – David C. Rankin Jul 19 '23 at 21:45