How to multiply two long numbers in C

2 Answers

0 votes
#include <stdio.h>
#include <string.h>
#include <ctype.h>

/*
  Multiply Two Long Numbers
  ------------------------------------
  Implements manual big‑integer multiplication
  using decimal strings.
*/

/* Multiply two integer strings a * b and store result in c.
   Caller must ensure c has enough space.
   c must not alias a or b. */
void longmulti(const char *a, const char *b, char *c) {
    int sign = 0;

    /* Skip leading spaces */
    while (*a == ' ') a++;
    while (*b == ' ') b++;

    /* Handle sign */
    if (*a == '-') { sign ^= 1; a++; }
    if (*b == '-') { sign ^= 1; b++; }

    /* Skip leading zeros */
    while (*a == '0' && a[1]) a++;
    while (*b == '0' && b[1]) b++;

    /* If either is "0", return "0" */
    if (strcmp(a, "0") == 0 || strcmp(b, "0") == 0) {
        c[0] = '0';
        c[1] = '\0';
        return;
    }

    int la = strlen(a);
    int lb = strlen(b);

    /* Initialize result buffer with '0' */
    memset(c, '0', la + lb);
    c[la + lb] = '\0';

    /* Multiply from right to left */
    for (int i = la - 1; i >= 0; i--) {
        if (!isdigit(a[i])) continue;
        int carry = 0;

        for (int j = lb - 1; j >= 0; j--) {
            if (!isdigit(b[j])) continue;

            int pos = i + j + 1;
            int n = (a[i] - '0') * (b[j] - '0')
                    + (c[pos] - '0') + carry;

            c[pos] = (n % 10) + '0';
            carry = n / 10;
        }

        c[i] += carry;
    }

    /* Remove leading zero if present */
    if (c[0] == '0')
        memmove(c, c + 1, la + lb);

    /* Add sign if needed */
    if (sign) {
        size_t len = strlen(c);
        memmove(c + 1, c, len + 1);
        c[0] = '-';
    }
}

int main()
{
    char result[2048] = "";

    longmulti(" 18361891827367132321",
              "-18361891827367132321",
              result);

    printf("%s\n", result);

    return 0;
}


/*
run:

-337159071479931885857929667075122847041

*/


 



answered 4 days ago by avibootz
edited 4 days ago by avibootz
0 votes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

// Function to multiply two absolute string numbers
char* multiplyAbsolute(const char* num1, const char* num2) {
    int n1 = strlen(num1);
    int n2 = strlen(num2);
    if (n1 == 0 || n2 == 0) {
        char* zero = malloc(2);
        strcpy(zero, "0");
        return zero;
    }

    // Result can have at most n1 + n2 digits
    // calloc initializes the array elements to 0
    int* result = calloc(n1 + n2, sizeof(int));

    // Shift positions from right to left
    for (int i = n1 - 1; i >= 0; i--) {
        for (int j = n2 - 1; j >= 0; j--) {
            int mul = (num1[i] - '0') * (num2[j] - '0');
            // Sum with the existing value at this position
            int sum = mul + result[i + j + 1];

            // Update the current position and the carry
            result[i + j + 1] = sum % 10;
            result[i + j] += sum / 10;
        }
    }

    // Convert vector back to string, skipping leading zeros
    // Allocate max possible size + 1 for null terminator
    char* resultStr = malloc(n1 + n2 + 1);
    int idx = 0;
    bool leadingZero = true;

    for (int i = 0; i < n1 + n2; i++) {
        if (result[i] == 0 && leadingZero) continue;
        leadingZero = false;
        resultStr[idx++] = result[i] + '0';
    }

    resultStr[idx] = '\0';
    free(result);

    // If the string is empty, it means the result was 0
    if (idx == 0) {
        strcpy(resultStr, "0");
    }

    return resultStr;
}

// Main function that manages signs and calls the multiplier
char* multiplyBigInt(const char* num1, const char* num2) {
    if (strcmp(num1, "0") == 0 || strcmp(num2, "0") == 0) {
        char* zero = malloc(2);
        strcpy(zero, "0");
        return zero;
    }

    // Determine the sign of the result
    bool isNegative = false;
    
    if (num1[0] == '-') {
        isNegative = !isNegative;
        num1++; // Remove '-' by advancing the pointer
    }
    if (num2[0] == '-') {
        isNegative = !isNegative;
        num2++; // Remove '-' by advancing the pointer
    }

    char* absResult = multiplyAbsolute(num1, num2);
    
    if (isNegative) {
        // Allocate space for '-', the digits, and '\0'
        char* finalResult = malloc(strlen(absResult) + 2);
        finalResult[0] = '-';
        strcpy(finalResult + 1, absResult);
        free(absResult);
        return finalResult;
    }

    return absResult;
}

int main() {
    const char* num1 = "18361891827367132321";
    const char* num2 = "-18361891827367132321";

    char* product = multiplyBigInt(num1, num2);

    printf("Num 1:   %s\n", num1);
    printf("Num 2:   %s\n", num2);
    printf("Product: %s\n", product);

    // Dynamic memory cleanup
    free(product);

    return 0;
}


/*
run:

Num 1:   18361891827367132321
Num 2:   -18361891827367132321
Product: -337159071479931885857929667075122847041

*/


 



answered 4 days ago by avibootz
...