Длинная арифметика: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) Нет описания правки |
Ctrlalt (обсуждение | вклад) Нет описания правки |
||
Строка 1: | Строка 1: | ||
== Хранение, ввод и вывод == | |||
class BigInteger { | |||
static const int BASE = 1e9; | |||
static const int BASE_LEN = 9; | |||
static const int MAX_SIZE = 1e4; | |||
int d[MAX_SIZE]; | |||
int size; | |||
public: | |||
BigInteger(long long val) { | |||
for (int i = 0; i < MAX_SIZE; i++) | |||
d[i] = 0; | |||
size = 0; | |||
if (val == 0) | |||
d[size++] = 0; | |||
while (val > 0) { | |||
d[size++] = val % BASE; | |||
val /= BASE; | |||
} | |||
} | |||
BigInteger(char val[]) { | |||
for (int i = 0; i < MAX_SIZE; i++) | |||
d[i] = 0; | |||
size = 0; | |||
for (int i = strlen(val) - 1; i >= 0; i -= BASE_LEN) { | |||
int digit = 0; | |||
for (int j = max(0, i - BASE_LEN + 1); j <= i; j++) | |||
digit = digit * 10 + val[j] - '0'; | |||
d[size++] = digit; | |||
} | |||
} | |||
void print() { | |||
static char spec[] = "%00d"; | |||
spec[2] += BASE_LEN; | |||
printf("%d", d[size - 1]); | |||
for (int i = size - 2; i >= 0; i--) | |||
printf(spec, d[i]); | |||
} | |||
}; | |||
== Сравнение == | |||
int cmp(const BigInteger &that) { | |||
if (size != that.size) | |||
return size < that.size ? -1 : 1; | |||
for (int i = size - 1; i >= 0; i--) { | |||
if (d[i] != that.d[i]) | |||
return d[i] < that.d[i] ? -1 : 1; | |||
} | |||
return 0; | |||
} | |||
== Сложение == | |||
BigInteger add(const BigInteger &that) { | |||
BigInteger res(0LL); | |||
int carry = 0; | |||
for (int i = 0; i < max(size, that.size) || carry != 0; i++) { | |||
long long x = 0LL + d[i] + that.d[i] + carry; | |||
res.d[i] = x % BASE; | |||
carry = x / BASE; | |||
} | |||
res.size = max(size, that.size) + 1; | |||
while (res.size > 1 && res.d[res.size - 1] == 0) | |||
res.size--; | |||
return res; | |||
} | |||
== Вычитание == | |||
Предполагается, что уменьшаемое больше вычитаемого. | |||
BigInteger sub(const BigInteger &that) { | |||
BigInteger res(0LL); | |||
int carry = 0; | |||
for (int i = 0; i < size || carry != 0; i++) { | |||
long long x = 0LL + d[i] - that.d[i] + carry; | |||
res.d[i] = (x + BASE) % BASE; | |||
carry = x < 0 ? -1 : 0; | |||
} | |||
res.size = size; | |||
while (res.size > 1 && res.d[res.size - 1] == 0) | |||
res.size--; | |||
return res; | |||
} | |||
== Умножение == | |||
{| | |||
| width="50%" | | |||
BigInteger mul(const BigInteger &that) { | |||
BigInteger res(0LL); | |||
for (int i = 0; i < size; i++) { | |||
int carry = 0; | |||
for (int j = 0; j < that.size || carry != 0; j++) { | |||
long long x = res.d[i + j] + 1LL * d[i] * that.d[j] + carry; | |||
res.d[i + j] = x % BASE; | |||
carry = x / BASE; | |||
} | |||
} | |||
res.size = size + that.size; | |||
while (res.size > 1 && res.d[res.size - 1] == 0) | |||
res.size--; | |||
return res; | |||
} | |||
| width="10px" | | |||
| width="50%" | | |||
BigInteger mul(int that) { | |||
BigInteger res(0LL); | |||
int carry = 0; | |||
for (int i = 0; i < size || carry != 0; i++) { | |||
long long x = 1LL * d[i] * that + carry; | |||
res.d[i] = x % BASE; | |||
carry = x / BASE; | |||
} | |||
res.size = size + 1; | |||
while (res.size > 1 && res.d[res.size - 1] == 0) | |||
res.size--; | |||
return res; | |||
} | |||
|} | |||
== Деление и взятие остатка == | |||
{| | |||
| width="50%" | | |||
| width="10px" | | |||
| width="50%" | | |||
BigInteger div(int that) { | |||
BigInteger res(0LL); | |||
int carry = 0; | |||
for (int i = size - 1; i >= 0; i--) { | |||
long long x = 1LL * carry * BASE + d[i]; | |||
res.d[i] = x / that; | |||
carry = x % that; | |||
} | |||
res.size = size; | |||
while (res.size > 1 && res.d[res.size - 1] == 0) | |||
res.size--; | |||
return res; | |||
} | |||
|} | |||
{| | |||
| width="50%" | | |||
| width="10px" | | |||
| width="50%" | | |||
int mod(int that) { | |||
int carry = 0; | |||
for (int i = size - 1; i >= 0; i--) | |||
carry = (1LL * carry * BASE + d[i]) % that; | |||
return carry; | |||
} | |||
|} | |||
== Ссылки на задачи == | == Ссылки на задачи == | ||
* [http://acmp.ru/?main=task&id_task=103 ACMP #103 — Снова A + B] | * [http://acmp.ru/?main=task&id_task=103 ACMP #103 — Снова A + B] |
Версия от 02:53, 15 августа 2014
Хранение, ввод и вывод
class BigInteger { static const int BASE = 1e9; static const int BASE_LEN = 9; static const int MAX_SIZE = 1e4; int d[MAX_SIZE]; int size; public: BigInteger(long long val) { for (int i = 0; i < MAX_SIZE; i++) d[i] = 0; size = 0; if (val == 0) d[size++] = 0; while (val > 0) { d[size++] = val % BASE; val /= BASE; } } BigInteger(char val[]) { for (int i = 0; i < MAX_SIZE; i++) d[i] = 0; size = 0; for (int i = strlen(val) - 1; i >= 0; i -= BASE_LEN) { int digit = 0; for (int j = max(0, i - BASE_LEN + 1); j <= i; j++) digit = digit * 10 + val[j] - '0'; d[size++] = digit; } } void print() { static char spec[] = "%00d"; spec[2] += BASE_LEN; printf("%d", d[size - 1]); for (int i = size - 2; i >= 0; i--) printf(spec, d[i]); } };
Сравнение
int cmp(const BigInteger &that) { if (size != that.size) return size < that.size ? -1 : 1; for (int i = size - 1; i >= 0; i--) { if (d[i] != that.d[i]) return d[i] < that.d[i] ? -1 : 1; } return 0; }
Сложение
BigInteger add(const BigInteger &that) { BigInteger res(0LL); int carry = 0; for (int i = 0; i < max(size, that.size) || carry != 0; i++) { long long x = 0LL + d[i] + that.d[i] + carry; res.d[i] = x % BASE; carry = x / BASE; } res.size = max(size, that.size) + 1; while (res.size > 1 && res.d[res.size - 1] == 0) res.size--; return res; }
Вычитание
Предполагается, что уменьшаемое больше вычитаемого.
BigInteger sub(const BigInteger &that) { BigInteger res(0LL); int carry = 0; for (int i = 0; i < size || carry != 0; i++) { long long x = 0LL + d[i] - that.d[i] + carry; res.d[i] = (x + BASE) % BASE; carry = x < 0 ? -1 : 0; } res.size = size; while (res.size > 1 && res.d[res.size - 1] == 0) res.size--; return res; }
Умножение
BigInteger mul(const BigInteger &that) { BigInteger res(0LL); for (int i = 0; i < size; i++) { int carry = 0; for (int j = 0; j < that.size || carry != 0; j++) { long long x = res.d[i + j] + 1LL * d[i] * that.d[j] + carry; res.d[i + j] = x % BASE; carry = x / BASE; } } res.size = size + that.size; while (res.size > 1 && res.d[res.size - 1] == 0) res.size--; return res; } |
BigInteger mul(int that) { BigInteger res(0LL); int carry = 0; for (int i = 0; i < size || carry != 0; i++) { long long x = 1LL * d[i] * that + carry; res.d[i] = x % BASE; carry = x / BASE; } res.size = size + 1; while (res.size > 1 && res.d[res.size - 1] == 0) res.size--; return res; } |
Деление и взятие остатка
BigInteger div(int that) { BigInteger res(0LL); int carry = 0; for (int i = size - 1; i >= 0; i--) { long long x = 1LL * carry * BASE + d[i]; res.d[i] = x / that; carry = x % that; } res.size = size; while (res.size > 1 && res.d[res.size - 1] == 0) res.size--; return res; } |
int mod(int that) { int carry = 0; for (int i = size - 1; i >= 0; i--) carry = (1LL * carry * BASE + d[i]) % that; return carry; } |