У меня есть реализация класса Long Integer, которая должна обеспечивать возможность выполнения арифметических c операций с экземплярами класса. Это работает в 95% случаев, но иногда показывает неправильные результаты. Экран с неправильными ответами находится под кодом.
HugeInt.h:
#ifndef _HUGEINGH
#define _HUGEINGH
#include <iostream>
#include <list>
#include <string>
#include <math.h>
using namespace std;
class HugeInt {
private:
char* listNumber;
int maxLength, length;
bool plus;
void expansion_size_length();
void updatingLength();
void set_listNumber(int position, char num);
char get_listNumber(int position);
char symbol_in_numeral(char symbol);
char numeral_in_symbol(char numeral);
public:
string toString();
void setNumber(string str);
HugeInt operator-(HugeInt HugeInt);
HugeInt operator+(HugeInt HugeInt);
HugeInt operator*(HugeInt HugeInt);
HugeInt(string str);
HugeInt();
HugeInt(const HugeInt &lg);
~HugeInt();
};
#endif
Hugeint. cpp:
#include "stdafx.h"
#include "HugeInt.h"
void HugeInt::expansion_size_length() {
char* tmp = new char[maxLength * 2];
for (int i = 0; i < maxLength; i++) {
tmp[i] = listNumber[i];
}
delete[] listNumber;
listNumber = tmp;
maxLength *= 2;
}
void HugeInt::updatingLength() {
while (length > 1) {
int tmp = listNumber[length - 1];
if (listNumber[length - 1] == 0) {
length--;
}
else {
return;
}
}
}
void HugeInt::set_listNumber(int position, char num) {
if (position < maxLength) {
listNumber[position] = num;
if (position >= length)
length = position + 1;
}
else {
while (position > maxLength)
expansion_size_length();
length = position + 1;
}
}
char HugeInt::get_listNumber(int position) {
if (position < length) {
return listNumber[position];
}
return 0;
}
char HugeInt::symbol_in_numeral(char symbol) {
return symbol - '0';
}
char HugeInt::numeral_in_symbol(char numeral) {
return numeral + '0';
}
string HugeInt::toString() {
string str = string();
if (!plus)
str.insert(str.size(), 1, '-');
for (int i = length - 1; i >= 0; i--) {
str.insert(str.size(), 1, numeral_in_symbol(listNumber[i] / 10));
str.insert(str.size(), 1, numeral_in_symbol(listNumber[i] % 10));
}
return str;
}
void HugeInt::setNumber(string str) {
//plus = true;
//maxLength = 10;
//listNumber = new char[maxLength];
length = 0; // дело в этом
delete[] listNumber;
listNumber = new char[str.length() + 1];
maxLength = str.length() + 1;
for (int i = length; i < maxLength; i++)
listNumber[i] = 0;
length = maxLength;
if (str.size() != 0) {
int k = 0;
if (str[0] == '-') {
plus = false;
for (int i = str.size() - 1; i > 0; i -= 2) {
if (i - 1 > 0)
listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
else listNumber[k] = symbol_in_numeral(str[i]);
k++;
}
}
else if (str[0] == '+') {
plus = true;
for (int i = str.size() - 1; i > 0; i -= 2) {
if (i - 1 > 0)
listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
else listNumber[k] = symbol_in_numeral(str[i]);
k++;
}
}
else {
plus = true;
for (int i = str.size() - 1; i >= 0; i -= 2) {
if (i - 1 >= 0)
listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
else listNumber[k] = symbol_in_numeral(str[i]);
k++;
}
}
}
updatingLength();
}
HugeInt HugeInt::operator-(HugeInt _HugeInt) {
HugeInt result = HugeInt();
if (_HugeInt.plus == this->plus) {
int length_tmp = _HugeInt.length > this->length ? _HugeInt.length : this->length;
char part_sub = 0;
int sub;
char tmp1, tmp2;
for (int i = 0; i < length_tmp; i++) {
tmp1 = listNumber[i];
tmp2 = _HugeInt.listNumber[i];
sub = ((int)listNumber[i] - (int)_HugeInt.listNumber[i] - (int)part_sub);
part_sub = 0;
if (sub < 0) {
sub += 100;
part_sub = 1;
}
//else if (sub == 0) //
//part_sub = 1; //
result.set_listNumber(i, sub);
}
if (part_sub != 0) {
part_sub = 0;
result.plus = !this->plus;
for (int i = 0; i < length_tmp; i++) {
sub = ((int)result.listNumber[i] + (int)part_sub - 100);//
part_sub = 0;
if (sub < 0) {
sub = abs(sub);
part_sub = 1;
}
//else if (sub == 0) //
//part_sub = 1; //
result.set_listNumber(i, sub % 100);
}
}
result.updatingLength();
return result;
}
else {
HugeInt lg1 = HugeInt(_HugeInt);
HugeInt lg2 = HugeInt(*this);
lg1.plus = !lg1.plus;
//HugeInt.plus = !HugeInt.plus;
return lg2 + lg1;
}
}
HugeInt HugeInt::operator+(HugeInt _HugeInt) {
HugeInt result = HugeInt();
if (_HugeInt.plus == this->plus) {
int length_tmp = _HugeInt.length > this->length ? _HugeInt.length : this->length;
char part_sum = 0;
char tmp1, tmp2;
for (int i = 0; i < length_tmp; i++) {
tmp1 = _HugeInt.listNumber[i];
tmp2 = listNumber[i];
result.set_listNumber(i, (_HugeInt.listNumber[i] + listNumber[i] + part_sum) % 100);
part_sum = (_HugeInt.listNumber[i] + listNumber[i] + part_sum) / 100;
}
if (part_sum != 0) {
result.set_listNumber(length_tmp, part_sum);
}
result.plus = plus;
result.updatingLength();
return result;
}
else {
if (_HugeInt.plus) {
//plus = !plus;
HugeInt lg1 = HugeInt(_HugeInt);
HugeInt lg2 = HugeInt(*this);
lg2.plus = !lg2.plus;
return lg1 - lg2;
}
else {
HugeInt lg1 = HugeInt(_HugeInt);
HugeInt lg2 = HugeInt(*this);
lg1.plus = !lg1.plus;
//HugeInt.plus != HugeInt.plus;
return lg2 - lg1;
}
}
}
HugeInt HugeInt::operator*(HugeInt _HugeInt) {
HugeInt result = HugeInt();
int part_mul;
int iter = 0;
HugeInt tmpHugeInt;
int tmp1, tmp2;
for (int i = 0; i < _HugeInt.length; i++) {
part_mul = 0;
tmpHugeInt = HugeInt();
for (int j = 0; j < length; j++) {
tmp1 = _HugeInt.listNumber[i];
tmp2 = listNumber[j];
iter = (int)_HugeInt.listNumber[i] * (int)listNumber[j] + (int)part_mul;
part_mul = iter / 100;
tmpHugeInt.set_listNumber(j + i, iter % 100);
}
if (part_mul != 0) {
tmpHugeInt.set_listNumber(tmpHugeInt.length, part_mul);
}
result = result + tmpHugeInt;
}
if (_HugeInt.plus != plus)
result.plus = false;
result.updatingLength();
return result;
}
HugeInt::HugeInt(string str) {
plus = true;
maxLength = 10;
listNumber = new char[maxLength];
length = 0;
setNumber(str);
}
HugeInt::HugeInt() {
plus = true;
maxLength = 10;
listNumber = new char[maxLength];
length = 0;
for (int i = length; i < maxLength; i++)
listNumber[i] = 0;
}
HugeInt::HugeInt(const HugeInt &lg) {
plus = lg.plus;
maxLength = lg.maxLength;
listNumber = new char[maxLength];
length = lg.length;
for (int i = 0; i < maxLength; i++)
if (i < lg.length){
listNumber[i] = lg.listNumber[i];
}
else{
listNumber[i] = 0;
}
}
HugeInt::~HugeInt() {
//delete[] listNumber;
}
main. cpp:
#include "stdafx.h"
#include "HugeInt.h"
int _tmain(int argc, _TCHAR* argv[])
{
/*
string num1, num2;
cout << "Enter the first number:" << endl;
cin >> num1;
cout << "Enter the second number:" << endl;
cin >> num2;
HugeInt hugeNum1 = HugeInt(num1);
HugeInt hugeNum2 = HugeInt(num2);
cout << "Entered the following numbers:" << endl;
cout << "First number: " << num1 << endl;
cout << "Second number: " << num2 << endl;
HugeInt sum = hugeNum1 + hugeNum2;
HugeInt sub = hugeNum1 - hugeNum2;
HugeInt mul = hugeNum1 * hugeNum2;
cout << "Summary = " << sum.toString() << endl;
cout << "Substruction = " << sub.toString() << endl;
cout << "Multiplacation = " << mul.toString() << endl;
*/
HugeInt longNumber1;
HugeInt longNumber2;
HugeInt longNumberRes;
/*
int firstTrue = 1837;
int secondTrue = -8108;
char buf[32];
itoa(firstTrue, buf, 10);
string firststr(buf);
itoa(secondTrue, buf, 10);
string secstr(buf);
longNumber1.setNumber(firststr);
longNumber2.setNumber(secstr);
longNumberRes = longNumber1 + longNumber2;
int res = atoi(longNumberRes.toString().c_str());
cout << "Good " << firstTrue << "+" << secondTrue << "=" << res << endl;
int firstFalse = 312;
int secondFalse = 712;
char buf2[32];
itoa(firstFalse, buf2, 10);
string firststr2(buf2);
itoa(secondFalse, buf2, 10);
string secstr2(buf2);
longNumber1.setNumber(firststr2);
longNumber2.setNumber(secstr2);
longNumberRes = longNumber1 - longNumber2;
int res2 = atoi(longNumberRes.toString().c_str());
cout << "Bad " << firstFalse << "-" << secondFalse << "=" << res2 << endl;
*/
for (int i = 0; i < 1000; i++)
{
int first = rand() % 20000 - 10000;
int second = rand() % 20000 - 10000;
char buf[32];
itoa(first, buf, 10);
string firststr(buf);
itoa(second, buf, 10);
string secstr(buf);
longNumber1.setNumber(firststr);
longNumber2.setNumber(secstr);
longNumberRes = longNumber1 - longNumber2;
int res = atoi(longNumberRes.toString().c_str());
if (res != first - second)
cout << i << " = "<< first << "+" << second << "=" << res << endl;
}
system("pause");
return 0;
}
Печатает следующие результаты, когда я делаю тест с 1000 случайными числами (5 из 1000 результатов неверны ):
48 = 6118+-7918=-1700
268 = -8887+4887=-3900
326 = 3169+-6169=-2900
474 = 212+-712=-400
492 = 1333+-7133=-5700
545 = 8352+-9552=-1100
617 = -4395+195=-4100
Похоже, что-то не так с минусовой операцией, но я не могу понять, что именно. Пожалуйста, помогите, что не так в реализации и как это исправить?
![enter image description here](https://i.stack.imgur.com/feIeV.jpg)