|
|
|
@ -4,15 +4,14 @@
|
|
|
|
|
#include "number.h"
|
|
|
|
|
|
|
|
|
|
Number::Number(int a)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
#ifdef _DEBUG_CONSTRUCTOR
|
|
|
|
|
std::cout << "(Number constructor " << a << " -> ";
|
|
|
|
|
#endif
|
|
|
|
|
// Находим размер необходимой памяти под это число
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
@ -37,19 +35,24 @@ Number::Number(int a)
|
|
|
|
|
#ifdef _DEBUG_CONSTRUCTOR
|
|
|
|
|
std::cout << *this << ")" << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Конструктор по умолчанию
|
|
|
|
|
Number::Number() : Number(0) {}
|
|
|
|
|
Number::Number():Number(0){}
|
|
|
|
|
|
|
|
|
|
// Конструктор копирования
|
|
|
|
|
Number::Number(const Number& n) {
|
|
|
|
|
Number::Number(const Number & n)
|
|
|
|
|
{
|
|
|
|
|
size = n.size;
|
|
|
|
|
capacity = n.capacity;
|
|
|
|
|
data = new char[capacity];
|
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
|
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) {
|
|
|
|
|
{
|
|
|
|
|
delete[]data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Number & Number::operator=(const Number & right)
|
|
|
|
|
{
|
|
|
|
|
capacity = right.capacity;
|
|
|
|
|
size = right.size;
|
|
|
|
|
data = new char[capacity];
|
|
|
|
@ -78,12 +83,15 @@ Number& Number::operator=(const Number& right) {
|
|
|
|
|
data[i] = right.data[i];
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
@ -97,7 +105,7 @@ Number Number::operator+(Number a) {
|
|
|
|
|
}
|
|
|
|
|
result.capacity = size + 1;
|
|
|
|
|
//result.data = new char[capacity];
|
|
|
|
|
result.data = (char*)calloc(result.capacity, sizeof(char));
|
|
|
|
|
result.data = (char *) calloc(result.capacity, sizeof(char));
|
|
|
|
|
for (i = 0; i < a.size; ++i) {
|
|
|
|
|
result.data[i] = (data[i] + a.data[i] + carry) % base;
|
|
|
|
|
carry = (data[i] + a.data[i] + carry) / base;
|
|
|
|
@ -112,37 +120,45 @@ 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;
|
|
|
|
|
Number result;
|
|
|
|
|
|
|
|
|
|
result.capacity = capacity + right.capacity;
|
|
|
|
|
int *carry = (int*)std::calloc(result.capacity, sizeof(int));
|
|
|
|
|
int *carry = (int *) std::calloc(result.capacity, sizeof(int));
|
|
|
|
|
|
|
|
|
|
result.data = (char*)calloc(result.capacity, sizeof(char));
|
|
|
|
|
result.data = (char *) calloc(result.capacity, sizeof(char));
|
|
|
|
|
#ifdef _DEBUG_MUL
|
|
|
|
|
std::cout << "carry:[" << carry[0];
|
|
|
|
|
for (int k = 1; k < result.capacity; ++k) {
|
|
|
|
@ -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));
|
|
|
|
@ -194,18 +215,23 @@ Number Number::operator*(const Number& right) const {
|
|
|
|
|
result.data[i] = temp_data[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(temp_data);*/
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
@ -215,13 +241,19 @@ bool Number::operator==(const Number& a) const {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
return not(*this == a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
@ -254,11 +290,15 @@ bool Number::operator>(const Number& a) const {
|
|
|
|
|
std::cout << "using final false" << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
bool Number::operator<(const Number& a) const {
|
|
|
|
|
return not (*this > a) and (*this != a);
|
|
|
|
|
}
|
|
|
|
|
void Number::div2() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Number::operator<(const Number & a) const
|
|
|
|
|
{
|
|
|
|
|
return not(*this > a) and(*this != a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Number::div2()
|
|
|
|
|
{
|
|
|
|
|
#ifdef _DEBUG_DIV2
|
|
|
|
|
std::cout << "n = " << *this << std::endl;
|
|
|
|
|
#endif
|
|
|
|
@ -269,31 +309,33 @@ void Number::div2() {
|
|
|
|
|
data[i] = temp / 2;
|
|
|
|
|
carry = temp % 2;
|
|
|
|
|
}
|
|
|
|
|
if (data[size-1] == 0) {
|
|
|
|
|
if (data[size - 1] == 0) {
|
|
|
|
|
--size;
|
|
|
|
|
}
|
|
|
|
|
#ifdef _DEBUG_DIV2
|
|
|
|
|
std::cout << "unstripped result "<< *this << std::endl;
|
|
|
|
|
std::cout << "unstripped result " << *this << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& stream, const Number& right)
|
|
|
|
|
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
|
|
|
|
|
// Печатаем самый большой разряд
|
|
|
|
|
stream << (int)right.data[right.size - 1];
|
|
|
|
|
stream << (int) right.data[right.size - 1];
|
|
|
|
|
|
|
|
|
|
// Печатаем остальные разряды с заполнением нулями до 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;
|
|
|
|
|
}
|
|
|
|
|