number final

master
nihonium 2 years ago
parent f0499e0d8c
commit c495b7c47f
No known key found for this signature in database
GPG Key ID: 0251623741027CFC

@ -4,14 +4,14 @@
#include <algorithm>
#include "number.h"
Number fib(int n) {
Number fib(int n)
{
Number a = 0; // F0
Number b = 1; // F1
for (int i = 1; i <= n; ++i) {
if (i % 2) {
a += b;
}
else {
} else {
b += a;
}
}
@ -21,15 +21,18 @@ Number fib(int n) {
return a;
}
Number factorial(int n) {
Number result{1};
Number factorial(int n)
{
Number result {
1};
for (int i = 2; i < n + 1; ++i) {
result = Number(i) * result;
}
return result;
}
void grad(Number n) {
void grad(Number n)
{
std::cout << "n = " << n;
Number max = n;
@ -43,8 +46,7 @@ void grad(Number n) {
}
if (n.isEven()) {
n.div2();
}
else {
} else {
n = Number(3) * n + Number(1);
}
#ifdef _DEBUG_GRAD
@ -60,18 +62,14 @@ void grad(Number n) {
int main()
{
std::cout << fib(1000) << std::endl;
//x = x * Number(24)*Number{25};
//y = factorial(5);
//std::cout << x << " " << x.capacity << " " << x.size << std::endl;
//std::cout << y << " "<< y.capacity << " " << y.size << std::endl;
//std::cout << "===" << std::endl << Number(2) * Number(3) << " "<< Number(3) * Number(2) << std::endl;
//std::cout << "5! = " << Number(2) * Number(3) * Number(4) * Number(5) << std::endl;
//std::cout << factorial(1000) << std::endl;
//std::cout << Number("620448401733239439360000") * Number(25) << std::endl;
//std::cout << (y < x) << std::endl;
//grad(Number("4761963248413673697"));
//grad(Number("256"));
//std::cout << Number(128) * Number(3) + Number(1) + Number(2) + Number(3) + Number(4) << std::endl;
std::cout << "===FIB===" << std::endl;
std::cout << "F(1000) = " << fib(1000) << std::endl;
std::cout << "===FAC===" << std::endl;
std::cout << "1000! = " << factorial(1000) << std::endl;
std::cout << "===GRAD===" << std::endl;
grad(Number("7"));
grad(Number("256"));
grad(Number("1117065"));
grad(Number("4761963248413673697"));
grad(Number("90560792656972947582439785608972465789628974587264056284658721771"));
}

@ -11,8 +11,7 @@ Number::Number(int a)
// Находим размер необходимой памяти под это число
int temp = a;
capacity = 0;
while (temp != 0)
{
while (temp != 0) {
temp /= base;
capacity += 1;
}
@ -26,8 +25,7 @@ Number::Number(int a)
data = new char[capacity];
for (int i = 0; i < capacity; ++i)
{
for (int i = 0; i < capacity; ++i) {
data[i] = a % base;
a /= base;
}
@ -38,10 +36,13 @@ Number::Number(int a)
std::cout << *this << ")" << std::endl;
#endif
}
// Конструктор по умолчанию
Number::Number():Number(0){}
// Конструктор копирования
Number::Number(const Number& n) {
Number::Number(const Number & n)
{
size = n.size;
capacity = n.capacity;
data = new char[capacity];
@ -49,7 +50,9 @@ Number::Number(const Number& n) {
data[i] = n.data[i];
}
}
Number::Number(const char* str) {
Number::Number(const char *str)
{
int len = std::strlen(str);
size = (len + len % 2) / 2;
capacity = size;
@ -59,18 +62,20 @@ Number::Number(const char* str) {
buf[1] = str[len - 2 * i - 1];
if (len - 2 * i - 1 > 0) {
buf[0] = str[len - 2 * i - 2];
}
else {
} else {
buf[0] = '0';
}
data[i] = std::stoi(buf);
}
}
Number::~Number()
{
delete[]data;
}
Number& Number::operator=(const Number& right) {
Number & Number::operator=(const Number & right)
{
capacity = right.capacity;
size = right.size;
data = new char[capacity];
@ -80,10 +85,13 @@ Number& Number::operator=(const Number& right) {
return *this;
}
Number Number::operator+(Number a) {
Number Number::operator+(Number a)
{
#ifdef _DEBUG_ADD
std::cout << "arg1=" << a << "capacity=" << a.capacity << ",size="<< a.size<< std::endl;
std::cout << "arg2=" << *this << "capacity=" << this->capacity << ",size="<< this->size<< std::endl;
std::cout << "arg1=" << a << "capacity=" << a.
capacity << ",size=" << a.size << std::endl;
std::cout << "arg2=" << *this << "capacity=" << this->
capacity << ",size=" << this->size << std::endl;
#endif
Number result;
@ -112,28 +120,36 @@ Number Number::operator+(Number a) {
#endif
result.data[i] = carry;
result.size = size + 1;
}
else {
} else {
result.size = size;
}
#ifdef _DEBUG_ADD
std::cout << result << " capacity=" << result.capacity << ",size="<<result.size<< std::endl;
std::cout << result << " capacity=" << result.
capacity << ",size=" << result.size << std::endl;
#endif
return result;
}
void Number::operator+=(const Number& a) {
void Number::operator+=(const Number & a)
{
*this = *this + a;
}
bool Number::isEven() const {
bool Number::isEven() const
{
if (data[0] % 2) {
return false;
}
return true;
}
Number Number::operator*(const Number& right) const {
Number Number::operator*(const Number & right) const
{
#ifdef _DEBUG_MUL
std::cout << "arg1=" << *this << "(capacity=" << capacity << ",size=" << size << ")" << " " << "arg2=" << right << "(capacity=" << right.capacity << ",size=" << right.size << ")"<< std::endl;
std::
cout << "arg1=" << *this << "(capacity=" << capacity << ",size=" <<
size << ")" << " " << "arg2=" << right << "(capacity=" << right.
capacity << ",size=" << right.size << ")" << std::endl;
#endif
int i, j;
int temp;
@ -153,9 +169,14 @@ Number Number::operator*(const Number& right) const {
for (i = 0; i < size; ++i) {
for (j = 0; j < right.size; ++j) {
#ifdef _DEBUG_MUL
std::cout << i + j << ":" << static_cast<int>(result.data[i + j]) << " + " << static_cast<int>(data[i]) << " * " << static_cast<int>(right.data[j]) << " + " << carry[i+j] << std::endl;
std::cout << i + j << ":" << static_cast <
int >(result.data[i + j]) << " + " << static_cast <
int >(data[i]) << " * " << static_cast <
int >(right.data[j]) << " + " << carry[i + j] << std::endl;
#endif
temp = (result.data[i + j] + data[i] * right.data[j] + carry[i + j]);
temp =
(result.data[i + j] + data[i] * right.data[j] +
carry[i + j]);
result.data[i + j] = temp % base;
carry[i + j + 1] += temp / base;
carry[i + j] = 0;
@ -173,13 +194,13 @@ Number Number::operator*(const Number& right) const {
if (carry[i + j - 1]) {
result.data[i + j - 1] = carry[i + j - 1];
result.size = i + j;
}
else {
} else {
result.size = i + j - 1;
}
#ifdef _DEBUG_MUL
std::cout << "before correcting capacity, result=" << result << std::endl;
std::cout << "before correcting capacity, result=" << result << std::
endl;
#endif
// correcting capacity
/*char* temp_data = (char *)calloc(result.size, sizeof(char));
@ -197,15 +218,20 @@ Number Number::operator*(const Number& right) const {
free(temp_data); */
free(carry);
#ifdef _DEBUG_MUL
std::cout << "return value=" << result << "(capacity=" << result.capacity << ",size=" << result.size << ")" << std::endl << "======" << std::endl;
std::cout << "return value=" << result << "(capacity=" << result.
capacity << ",size=" << result.
size << ")" << std::endl << "======" << std::endl;
#endif
return result;
}
void Number::operator*=(const Number& a) {
void Number::operator*=(const Number & a)
{
*this = *this * a;
}
bool Number::operator==(const Number& a) const {
bool Number::operator==(const Number & a) const
{
if (size != a.size) {
return false;
}
@ -216,12 +242,18 @@ bool Number::operator==(const Number& a) const {
}
return true;
}
bool Number::operator!=(const Number& a) const {
bool Number::operator!=(const Number & a) const
{
return not(*this == a);
}
bool Number::operator>(const Number& a) const {
bool Number::operator>(const Number & a) const
{
#ifdef _DEBUG_COMP
std::cout << "comp " << *this << "(size=" << size << ") and " << a << "(size=" << a.size << ")" << std::endl;
std::
cout << "comp " << *this << "(size=" << size << ") and " << a <<
"(size=" << a.size << ")" << std::endl;
#endif
if (size > a.size) {
#ifdef _DEBUG_COMP
@ -239,12 +271,16 @@ bool Number::operator>(const Number& a) const {
if (data[i] > a.data[i]) {
return true;
#ifdef _DEBUG_COMP
std::cout << static_cast<int>(data[i]) << ">" << static_cast<int>(a.data[i]) << std::endl;
std::cout << static_cast <
int >(data[i]) << ">" << static_cast <
int >(a.data[i]) << std::endl;
#endif
}
if (data[i] < a.data[i]) {
#ifdef _DEBUG_COMP
std::cout << static_cast<int>(data[i]) << "<" << static_cast<int>(a.data[i]) <<std::endl;
std::cout << static_cast <
int >(data[i]) << "<" << static_cast <
int >(a.data[i]) << std::endl;
#endif
return false;
}
@ -255,10 +291,14 @@ bool Number::operator>(const Number& a) const {
#endif
return false;
}
bool Number::operator<(const Number& a) const {
bool Number::operator<(const Number & a) const
{
return not(*this > a) and(*this != a);
}
void Number::div2() {
void Number::div2()
{
#ifdef _DEBUG_DIV2
std::cout << "n = " << *this << std::endl;
#endif
@ -283,7 +323,8 @@ std::ostream& operator<<(std::ostream& stream, const Number& right)
#ifdef _DEBUG_COUT
stream << "[";
for (std::size_t i = 0; i < right.size; ++i) {
stream << static_cast<int>(right.data[right.size - 2 - i]) << ",";
stream << static_cast <
int >(right.data[right.size - 2 - i]) << ",";
}
stream << "]";
#else
@ -293,7 +334,8 @@ std::ostream& operator<<(std::ostream& stream, const Number& right)
// Печатаем остальные разряды с заполнением нулями до 2-х цифр
// setfill и setw это то же самое, что и в языке C спецификатор %02d
for (std::size_t i = 0; i < right.size - 1; ++i)
stream << std::setfill('0') << std::setw(2) << (int)right.data[right.size - 2 - i];
stream << std::setfill('0') << std::setw(2) << (int) right.
data[right.size - 2 - i];
#endif
return stream;
}

@ -25,8 +25,7 @@
(это упрощает многие алгоритмы с такими числами)
*/
class Number
{
class Number {
private:
static const int base = 100;
std::size_t size;
@ -57,7 +56,8 @@ public:
bool operator<(const Number & a) const;
void div2();
friend std::ostream& operator<<(std::ostream& stream, const Number& right);
friend std::ostream & operator<<(std::ostream & stream,
const Number & right);
};
std::ostream & operator<<(std::ostream & stream, const Number & right);