简体   繁体   中英

Subtracting arbitrary large integers in C

Question:

  • I want to know the difference of number n and a, both stored in char arrays in ALI structures. Basically, what I'm doing is initialising two integers (temp_n and temp_a) with the current digits of n and a, subtracting them and placing the result in a new ALI instance named k. If the j-th digits of a is greater than the i-th digit of n, then I add 10 to the digit if n, finish the subtraction, and in the next turn, I increase temp_a by one. The value of number a certainly falls between 1 and n - 1 (that's given). If a is shorter than n, as soon as I reach the last digits of a, I put the remaining digits of n to the result array k. And I do this all backwards, so the initialising value of i would be the size of n -1.

Example:

  • I store a number in a structure like this:

     typedef struct Arbitrary_Large_Integer { char digits[]; } ALI;

Requirements:

  • I know that it could be easier to use char arrays instead of a structure with a single member which barely makes sense, but I'm forced to put structures in my code this time (that's a requirement for my assignment).

Code:

ALI *subtraction(ALI n, ALI a, int nLength, int aLength)
{
    ALI *result;
    result = (ALI*)malloc(nLength * sizeof(ALI));
    if (result == NULL)
    printf("ERROR");

    int temp_n, temp_a, difference; 
    int i = nLength - 1; //iterator for number 'n'
    int j = aLength - 1; //iterator for number 'a'
    int k = 0; //iterator for number 'k', n - a = k
    bool carry = false; //to decide whether a carry is needed or not the turn

    for (i; i >= 0; i--)
    {
         //subtracting 48 from n.digits[i], so temp_n gets the actual number 
         //and not its ASCII code when the value is passed
         temp_n = n.digits[i] - ASCIICONVERT; 
         temp_a = a.digits[j] - ASCIICONVERT;

        //Performing subtraction the same way as it's used on paper
        if (carry) //if there is carry, a needs to be increased by one
       {
              temp_a++;
              carry = false;
        }
              if (temp_n >= temp_a)
              {
                   difference = temp_n - temp_a;
               }
              //I wrote else if instead of else so I can clearly see the condition
             else if (temp_a > temp_n) 
            {
                 temp_n += 10;
                 difference = temp_n - temp_a;
                 carry = true;
            }

            //placing the difference in array k, but first converting it back to ASCII
            result->digits[k] = difference + ASCIICONVERT; 
            k++;

           //n is certainly longer than a, so after every subtraction is performed on a's digits,
           //I place the remaining digits of n in k
           if (j == 0) 
           {
                for (int l = i - 1; l >= 0; l--)
               {
                    result->digits[k] = n.digits[l];
                    k++;
                }

            //don't forget to close the array
            result->digits[k] = '\0';
            break;
          }
          j--;
      }

      //reverse the result array
     _strrev(result->digits);
     return result;
}

Output/Error:

Output results

  • It seems like when the array is passed to the function, its value changes for some reason. I can't figure out what's wrong with it.

Problems:

Non-standard C

The typedef is not a valid standard C structure. The Flexible Array Member(FAM) .digits must be accompanied by at least one more prior named member in addition to the flexible array member. Recommend to put .nLength as the first member.

// Not standard 
typedef struct Arbitrary_Large_Integer {
   char digits[];
} ALI;

malloc(0) ??

Since code is using a non-standard C, watch out that nLength * sizeof(ALI) may be the same as nLength * 0 .

No room for the null character

Code is attempting to use .digits as a string with _strrev() , the mallloc() is too small by 1, at least.

Other problems may exist

A Minimal, Complete, and Verifiable example is useful for additional fixes/solutions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM