Программирование >>  Немодифицирующие последовательные алгоритмы 

1 ... 69 70 71 [ 72 ] 73 74 75 ... 78


if (Р[0] / а != b) { P.push back(0);

DDproductIa, b, P[l], P[0]);

reduce();

neg = DifSigns, return *this;

if (L == 1) && Ly > 1

{ uint digit = P[0] ;

*this = y; Поменять местами операнды

*this *= digit; и вызвать operator*=(uint у)

} else

if (Ly == 1) && L > 1

{ *this *= y.P[0]; Вызвать operator*=(uint y) } else

Длины обоих операндов L и Ly больше 1: { int lenProd = L + Ly, i, jA, jB;

uint sumHi = 0, sumLo, Hi, Lo,

sumLoOld, sumHiOld, carry=0;

large x = *this;

SetLen(lenProd); Установить длину *this

равной lenProd for (i=0; i<lenProd; i++)

{ sumLo = sumHi; sumHi = carry; carry = 0; int max jA = min(i, L-1); jA <= i гарантирует jB >= 0

jA < L, поскольку в *this имеется лишь L цифр for (jA=max(0, i+l-Ly); jA<=max jA; jA++) jA > i - Ly гарантирует jB < Ly { jB = i - jA;

Другое произведение цифр, влияющее на

позицию i (= jA + jB) произведения

всего числа:

DDproduct(х.Р[jA], y.P[jB], Hi, Lo); sumLoOld = sumLo; sumHiOld = sumHi; sumLo += Lo; if (sumLo < sumLoOld)

sumHi++; sumHi += Hi;

carry += (sumHi < sumHiOld);

P[i] = sumLo;

reduce();

neg = DifSigns;



large &large: :operator = (uint k) { int q = к / wLen; Количество полных слов, if (q)

{ int i; Увеличить длину на q:

SetLen(P.size() + q);

Сдвинуть *this на q слов влево:

for (i=P.size()-l; i>=0; i--)

P[i] = (i < q ? 0 : P[i - q] ) ;

к %= wLen; Теперь к содержит оставшиеся

} позиции сдвига.

if (к) О < к < wLen: { int kl = wLen - к;

uint mask = (1 к) - 1;

маска: 00..Oil..1 (к единичных бит)

SetLen(Р.size() + 1);

Каждый из P[i] сдвигается на к позиций влево, а затем комбинируется по или с к самыми левыми битами правого соседа P[i-1]: for (int i=P.size()-1; i>=0; i--) { P[i] = k; if (i > 0)

P[i] 1= (P[i-1] kl) & mask;

reduce(); return *this;

return *this;

large &large::operator/=(const large &divisor) { large r;

Разделить *this на делитель, сохраняя результат в *this; О означает, что остаток в г не обязан быть правильным: divide(divisor, *this, г, 0) ; return *this;

large &large::operator%=(const large &divisor) { large q;

Разделить *this на делитель, сохраняя результат в *this; 1 означает, что остаток в г должен быть правильным: divide(divisor, q, *this, 1); return *this;



large &large::operator>>=(uint k) Аналогично = { int q = к / wLen, L = P.sizeO;

if (q >= L){*this = 0; return *this;}

if (q)

{ for (int i=q; i<L; i++) P[i-q] = P[i]; SetLen(L - q); к %= wLen;

if (k == 0) {reduced; return *this;}

int n = P.sizeO - 1, kl = wLen - k; uint mask = (1 k) - 1; for (int i=0; i<=n; i++) { P[i] = k;

if (i < n) P[i] 1= ((P[i+1] & mask) kl);

reduce(); return *this;

compare возвращает: отрицательное число, если *this < у, ноль, если *this == у, и положительное, если *this > у. int large::compare(const large &y)const { if (neg != y.neg) return y.neg - neg;

int code = 0, L = P.size(), Ly = y.P.sizeO;

if (L == 0 II Ly == 0) code = L - Ly; else

if (L < Ly) code = -1; else

if (L > Ly) code = +1; else

for (int i = L - 1; i >= 0; i--)

{ if (P[i] > y.P[i]) {code = 1; break;} else if (P[i] < y.P[i]) {code = -1; break;}

return neg ? -code : code;

Двуцифровое произведение (Hi, Lo) = A * B: void large::DDproduct(uint A, uint B,

uint &Hi, uint &Lo)const { uint hiA = A hLen, loA = A & rMask, hiB = В hLen, loB = В & rMask, midl, mid2, old; Lo = loA * loB; Hi = hiA * hiB; midl = loA * hiB; mid2 = hiA * loB; old = Lo;

Lo += midl hLen;

Hi += (Lo < old) + (midl >> hLen);

old = Lo;

Lo += mid2 hLen;

Hi += (Lo < old) + (mid2 hLen);



1 ... 69 70 71 [ 72 ] 73 74 75 ... 78

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика