Задача такая: Определить класс CIntN для работы с целыми знаковыми числами, состоящими lо N десятичных цифр, где N задается в конструкторе.
В классе должны быть определены необходимые конструкторы, деструктор, операторы присваивания, сложения, вычитания.
Написать функцию и конструктор сохранения переменной данного типа в файл и загрузки из файла. В отдельном файле должен быть написан тест на данный класс.
В процессе сдачи преподаватель попросил переписать тип данных на входе из char в String. Но почему-то теперь неверные значения сумм выходят. Никак не получается найти ошибку. Помогите, пожалуйста, советом
func.cpp
#include <string>
#include "func.h"
using namespace std;
vector<CIntN*> input(string sf)
{
vector<CIntN*> nums;
ifstream fin(sf);
string str;
if (fin.is_open())
{
string str;
for (; getline(fin, str);)
{
char type = str[0];
string number=str.substr(2);
if (type=='0')
{
CIntN* num = new CIntN0(number);
nums.push_back(num);
//delete num;
}
else
{
CIntN* num = new CIntN1(number);
nums.push_back(num);
//delete num;
}
}
fin.close();
}
return nums;
}
CIntN0 sum(vector<CIntN*> t)
{
const int n = t.size();
CIntN0 res("0");
for (int i = 0; i < n; i++)
{
res += *t[i];
}
return res;
}
CIntN0 sumOmp(vector<CIntN*> t)
{
const int n = t.size();
CIntN0 res("0");
#pragma omp declare reduction(+:CIntN:omp_out=omp_out+omp_in)//initializer(omp_priv=omp_orig)
#pragma omp parallel for reduction(+:res)
for (int i = 0; i < n; i++)
{
res = res + *t[i];
}
return res;
}
void CIntGen(const int n, int max)
{
ofstream fout("input.txt");
for (int i = 0; i < n; i++)
{
fout << rand() % 2 << ' ' << rand() % max << '\n';
}
fout << 0 << ' ' << 0 << '\0';
fout.close();
}
void output(vector<CIntN*> t)
{
for (auto it=t.begin();it!=t.end();++it)
{
CIntN* td = *it;
td->output();
}
}
CIntN.cpp
#include "CIntN.h"
CIntN::CIntN(string number)
{
setZero();
if (number.length())
{
int j = 0;
if (number[0] == '-')
{
sign = '-';
num = new int[this->n = number.length() - 1];
for (int i = n; i > 0; i--) { num[j] = (int)number[i] - 48; j++; }
}
else
{
sign = '+';
num = new int[this->n = number.length()];
for (int i = n - 1; i > -1; i--) { num[j] = (int)number[i] - 48; j++; }
}
}
}
CIntN CIntN::operator+(const CIntN& b)
{
int N;
if (n >= b.n) N = n + 1;
else N = b.n + 1;
CIntN x = N; x.sign = sign;
for (int i = 0; i < n; i++) x.num[i] = num[i];
for (int i = n; i < N; i++) x.num[i] = 0;
CIntN y = N; y.sign = b.sign;
for (int i = 0; i < b.n; i++) y.num[i] = b.num[i];
for (int i = b.n; i < N; i++) y.num[i] = 0;
CIntN res = N;
if (x.sign == y.sign)
{
res.sign = x.sign;
for (int i = 0; i < N; i++)
{
if (x.num[i] + y.num[i] > 9)
{
for (int j = i + 1; j < N; j++) if (x.num[j] != 9) { x.num[i + 1]++; break; }
}
res.num[i] = (x.num[i] + y.num[i]) % 10;
}
}
else
{
if (x.sign == '+') { y.sign = '+'; return x - y; }
else { x.sign = '+'; return y - x; }
}
for (int i = N - 1; i > -1; i--)
{
if (res.num[i] == 0) N--;
else break;
}
CIntN c = N; c.sign = res.sign;
for (int i = 0; i < N; i++) c.num[i] = res.num[i];
return c;
}
CIntN CIntN::operator-(const CIntN& b)
{
int N;
if (n >= b.n) N = n;
else N = b.n;
CIntN x = N; x.sign = sign;
for (int i = 0; i < n; i++) x.num[i] = num[i];
for (int i = n; i < N; i++) x.num[i] = 0;
CIntN y = N; y.sign = b.sign;
for (int i = 0; i < b.n; i++) y.num[i] = b.num[i];
for (int i = b.n; i < N; i++) y.num[i] = 0;
CIntN res = N;
if (x.sign == y.sign)
{
if (x > y)
{
res.sign = x.sign;
for (int i = 0; i < N; i++)
{
if (x.num[i] - y.num[i] < 0)
{
int j = i + 1;
while (x.num[j] == 0 && j < N) { x.num[j] = 9; j++; }
if (j < N)
{
x.num[j]--;
res.num[i] = x.num[i] + 10 - y.num[i];
}
else { for (j = 0; j < N; j++) { res.num[j] = 0; } break; }
}
else res.num[i] = x.num[i] - y.num[i];
}
}
else if (x < y)
{
res.sign = '-';
for (int i = 0; i < N; i++)
{
if (y.num[i] - x.num[i] < 0)
{
int j = i + 1;
while (y.num[j] == 0 && j < N) { y.num[j] = 9; j++; }
if (j < N)
{
y.num[j]--;
res.num[i] = y.num[i] + 10 - x.num[i];
}
else { for (j = 0; j < N; j++) { res.num[j] = 0; } break; }
}
else res.num[i] = y.num[i] - x.num[i];
}
}
else
{
CIntN c = 1;
c.num[0] = 0;
return c;
}
}
else
{
if (x.sign == '+') { y.sign = '+'; return x + y; }
else { y.sign = '-'; return x + y; }
}
for (int i = N - 1; i > -1; i--)
{
if (res.num[i] == 0) N--;
else break;
}
CIntN c = N; c.sign = res.sign;
for (int i = 0; i < N; i++) c.num[i] = res.num[i];
return c;
}
CIntN CIntN::operator+=(const CIntN& b)
{
int N;
if (n >= b.n) N = n + 1;
else N = b.n + 1;
CIntN x = N; x.sign = sign;
for (int i = 0; i < n; i++) x.num[i] = num[i];
for (int i = n; i < N; i++) x.num[i] = 0;
CIntN y = N; y.sign = b.sign;
for (int i = 0; i < b.n; i++) y.num[i] = b.num[i];
for (int i = b.n; i < N; i++) y.num[i] = 0;
CIntN res = N;
if (x.sign == y.sign)
{
res.sign = x.sign;
for (int i = 0; i < N; i++)
{
if (x.num[i] + y.num[i] > 9)
{
for (int j = i + 1; j < N; j++) if (x.num[j] != 9) { x.num[i + 1]++; break; }
}
res.num[i] = (x.num[i] + y.num[i]) % 10;
}
}
else
{
if (x.sign == '+') { y.sign = '+'; return x - y; }
else { x.sign = '+'; return y - x; }
}
for (int i = N - 1; i > -1; i--)
{
if (res.num[i] == 0) N--;
else break;
}
CIntN c = N; c.sign = res.sign;
for (int i = 0; i < N; i++) c.num[i] = res.num[i];
*this=c;
return *this;
}
bool CIntN::operator>(const CIntN& b)
{
if (n == b.n)
{
for (int i = n - 1; i > -1; i--) if (num[i] != b.num[i]) return num[i] > b.num[i];
}
else return n > b.n;
return false;
}
bool CIntN::operator<(const CIntN& b)
{
if (n == b.n)
{
for (int i = n - 1; i > -1; i--) if (num[i] != b.num[i]) return num[i] < b.num[i];
}
else return n < b.n;
return false;
}
string CIntN::makeStr()
{
string num = "";
if (sign == '-') num += '-';
for (int i = n - 1; i > -1; i--) num += (this->num[i] + 48);
return num;
}
void CIntN::output()
{
if (sign == '-') cout << sign;
for (int i = n - 1; i > -1; i--) cout << num[i];
cout << endl;
}
void CIntN::print()
{
if (sign == '-') cout << sign;
for (int i = n - 1; i > -1; i--) cout << num[i];
cout << endl;
}
CIntN.h
#pragma once
#include <iostream>
#include <fstream>
#include <istream>
#include <string.h>
using namespace std;
class CIntN
{
private:
int* num; int n; char sign;
public:
//---
CIntN() { setZero(); }
CIntN(int n) { setZero(); if (n) num = new int[this->n = n]; sign = '+'; }
CIntN(const CIntN& b) { copyOnly(b); }
CIntN(CIntN&& b) { n = b.n; num = b.num; sign = b.sign; b.setZero(); }
CIntN(string number);
CIntN& operator=(const CIntN& b) { if (&b != this) { clean(); copyOnly(b); } return *this; }
CIntN& operator=(CIntN&& b) { if (&b != this) { clean(); n = b.n; sign = b.sign; num = b.num; b.setZero(); } return *this; }
virtual ~CIntN() { clean(); }
//---
void setZero() { num = nullptr; n = 0; sign = ' '; }
void clean() { delete[] num; setZero(); }
void copyOnly(const CIntN& b) { setZero(); if (b.size()) { memcpy(num = new int[n = b.n], b.num, b.n * sizeof(*num)); } sign = b.sign; }
//---
string makeStr();
virtual void output();
void print();
//---
size_t size() const { return n; }
CIntN operator+(const CIntN& b);
CIntN operator-(const CIntN& b);
CIntN operator+=(const CIntN& b);
bool operator>(const CIntN& b);
bool operator<(const CIntN& b);
};
CIntN0.cpp
#include "CIntN0.h"
void CIntN0::output()
{
ofstream fout("output0.txt",ios::app);
fout << makeStr() << endl;
fout.close();
}
CIntN0.h
#pragma once
#include "CIntN.h"
class CIntN0 :
public CIntN
{
public:
CIntN0() :CIntN() {}
CIntN0(int n) : CIntN(n) {}
CIntN0(const CIntN& b) : CIntN(b) {}
CIntN0(CIntN&& b) : CIntN(b) {}
CIntN0(string number) :CIntN(number) {}
void output();
};
CIntN1.cpp
#include "CIntN1.h"
void CIntN1::output()
{
ofstream fout("output1.txt",ios::app);
fout << makeStr() << ' ';
fout.close();
}
CIntN1.h
[#pragma once
#include "CIntN.h"
class CIntN1 :
public CIntN
{
public:
CIntN1() :CIntN() {}
CIntN1(int n) : CIntN(n) {}
CIntN1(const CIntN& b) : CIntN(b) {}
CIntN1(CIntN&& b) : CIntN(b) {}
CIntN1(string number) :CIntN(number) {}
void output();
};
func.h
#pragma once
#include <vector>
#include <omp.h>
#include <time.h>
#include "CIntN0.h"
#include "CIntN1.h"
vector<CIntN*> input(string sf);
CIntN0 sum(vector<CIntN*> t);
CIntN0 sumOmp(vector<CIntN*> t);
void CIntGen(const int n, int max);
void CIntGenOmp(const int n, int max);
void output(vector<CIntN*> t);
main.cpp
#include "func.h"
int main(void)
{
srand(time(NULL));
time_t t1, t2, dt1;
CIntGen(100000000, 1000000);
vector<CIntN*> tn = input("input.txt");
t1 = clock();
sum(tn).print();
t2 = clock();
dt1 = (t2 - t1);
cout << "Without OMP: " << dt1 << endl;
for(auto &p:tn)
{
delete p;
p=nullptr;
}
tn = input("input.txt");
t1 = clock();
sumOmp(tn).print();
t2 = clock();
dt1 = (t2 - t1);
cout << "With OMP: " << dt1 << endl;
for(auto &p:tn)
{
delete p; p=nullptr;
}
return 0;
}