Алгоритм Карацубы в Javascript

Я реализовал алгоритм Карацубы на Javascript.

const multiply = (a, b) => {
    let sizeA = numOfDigits(a);
    let sizeB = numOfDigits(b);
    if(sizeA < sizeB) {
        a = '0'.repeat(sizeB-sizeA).concat(a);
    }
    else if(sizeB < sizeA) {
        b = '0'.repeat(sizeA - sizeB).concat(b);
    }
    if (numOfDigits(a) === 1 && numOfDigits(b) === 1) {
        return a * b;
    } else {
        let n = numOfDigits(a);
        n = ( n % 2 === 0 ) ? n : n + 1;
        let n_2 =  parseInt(Math.ceil(n /2));
        let splitA = reduceInHalf(a);
        let splitB = reduceInHalf(b);
        let p = splitA[0];
        let q = splitA[1];
        let r = splitB[0];
        let s = splitB[1];
        let u = multiply(p, r);
        let v = multiply((q - p).toString(), (s - r).toString());
        let w = multiply(q, s);
        let product = u * Math.pow(10,n) + (u + w - v) * Math.pow(10, n_2) + w;
        return product;
    }
}

Это терпит неудачу, когда я передаю очень большие числа, скажем, 2 числа из 64 цифр. Я попадаю в проблему с максимальным стеком вызовов. Я также столкнулся с другой реализацией, которая вернула неверный результат.

Все работает нормально с 2 номерами по 32 цифры каждый. Он переходит в непрерывную рекурсию, как только я ввожу 2 64-значных числа. Можно ли заставить это работать?


person Mayur Arora    schedule 12.11.2016    source источник


Ответы (1)


Похоже, вы полагаетесь на числовую функциональность JavaScript для различных частей (например, q - p и всех u * Math.pow(10,n) + (u + w - v) * Math.pow(10, n_2) + w); но числа JavaScript представляют собой значения с плавающей запятой двойной точности. Они не могут точно представлять целые числа из более чем 16 цифр. (См. "самое большое целое число, которое может быть сохранено в двойном".)

Если вы хотите заниматься математикой с очень большими целыми числами, вам нужно либо найти библиотеку больших целых чисел, либо управлять ею самостоятельно (используя строки, массивы или еще что-то).

person ruakh    schedule 12.11.2016