mnożenie pisemne

0

Mam program, który musi liczyć duże liczby, niestety przy mnożeniu wyrzuca błędy:

Number& Number::operator*(Number& other) {
	static Number Product;
	Product.Number::~Number();
	if (Product.digits != NULL)
		delete[] Product.digits;

	Number *ptrBigger, *ptrSmaller;
	if (current >= other.current) {
		ptrBigger = this;
		ptrSmaller = &other;
	}
	else {
		ptrBigger = &other;
		ptrSmaller = this;
	}
	Product.current = ptrBigger->current + ptrSmaller->current - 1;
	Product.digits = new char[Product.current];

	int addSome = 0;
	int multiplier = 0;

	for (int i = ptrSmaller->current - 1;i >= 0;i--) {
		for (int j = ptrBigger->current - 1;j >= 0;j--) {
			Product.digits[j-multiplier] = Product.digits[j-multiplier] + ptrBigger->digits[j] * ptrSmaller->digits[i] + addSome;
			if (Product.digits[j-multiplier] > 9) {
				addSome = Product.digits[j-multiplier] / 10;
				Product.digits[j-multiplier] = Product.digits[j-multiplier] % 10;
			}
			else
				addSome = 0;
		}
		++multiplier;
	}
		Product.digits[0] = addSome;

	return Product;
}

9fdac9fdcd.png

wiem, że ten static nie powinien tam być, ale prowadzący się przy nich upiera. Wie ktoś, jak to naprawić?

2

słyszałeś może o std::string?
Użyj.

3

Wyłazisz gdzieś poza zakres tablicy. Gdybym miał zgadywać to robisz to przez j-multiplier bo j zmierza do 0 podczas gdy multiplier rośnie. W efekcie będziesz tam miał gdzieś odwołanie do ujemnego indeksu w tablicy. Już po jednym obrocie pętli multiplier wynosi 1 a pętla z j schodzi do 0 więc w jej ostatnim obrocie odwołasz się do indeksu -1 w tablicy, czyli będziesz pisał poza zakresem.

3
    static Number Product;
    Product.Number::~Number();
    if (Product.digits != NULL)

UB.

static - nie wierzę, że prowadzący jest aż tak głupi - wklej treść zadania.

Więcej nie można powiedzieć, bo nie wstawiłeś kodu, a szklana kula na urlopie.

2

Product.Number::~Number();
if (Product.digits != NULL)
delete[] Product.digits;

Używasz obiektu po jego destrukcji. To raz.
Dezalokacja pamięci powinna być wewnątrz destruktora. To dwa.
Alokacja pamięci powinna być wewnątrz konstruktora. To trzy.
Ten static jest tam idiotyzmem. To cztery.

Jeśli już tak „musi być” to żeby utworzyć obiekt na nowo po ręcznym wywołaniu destruktora, należy użyć placement new.

Ale to i tak jest WTF.

0

bigNumbers.h:

#ifndef bigNumbers_h
#define bigNumbers_h

#include <iostream>
#include <cstdio>

const int STARTSIZE = 10;

using namespace std;

class Number {
protected:
	int size, current;
	char *digits;

public:
	Number();
	~Number();
	Number(const Number& other);

	friend ostream& operator<<(ostream & s, const Number & p1);
	friend istream& operator>>(istream & s, Number & p1);

	Number& operator=(const Number& p1);
	Number& operator+(Number& other);
	Number& operator*(Number& other);
	Number& operator+=(Number& other);


	void reallocSize();
	


};

class derNumber : public Number {

public:
	derNumber();
	~derNumber();
	derNumber(const derNumber& other);

	derNumber& operator=(const Number& other);
};

#endif

bigNumbers.cpp:

#include <iostream>
#include <cstdio>
#include <assert.h>
#include <algorithm>
#include <vector> 
#include "bigNumbers.h"

using namespace std;
										//KLASA PODSTAWOWA
Number::Number() {
	//cout << "Jestem konstruktor Number" << endl;
	current = 0;
	size = 0;
	digits = NULL;
}

Number::Number(int current) {
	//cout << "Jestem konstruktor Number" << endl;
	size = current / 10 * 10 + 10;
	digits = NULL;
}


Number::~Number() {
	//cout << endl << "Jestem destruktor Number";
	if (digits != NULL) {
		delete[] digits;
		digits = NULL;
	}
}

Number::Number(const Number& other){
	//cout << endl << "Jestem konstruktor kopiujący Number";
	if (digits != NULL)
		delete[] digits;
	size = other.size;
	digits = new char[size];
	current = other.current;
	for (int i = 0;i < other.current; i++)
		digits[i] = other.digits[i];
}

Number& Number::operator=(const Number& other) {
	if (this == &other)
		return *this;

	if (digits != NULL)
		delete[] digits;

	size = other.size;
	current = other.current;
	digits = new char[size];
	for (int i = 0; i < current; i++)
		digits[i] = other.digits[i];

	return *this;
}

Number& Number::operator+(Number& other) {
	static Number Sum;
	Sum.Number::~Number();
	Number *ptrBigger, *ptrSmaller;

	if (current >= other.current) {
		ptrBigger = this;
		ptrSmaller = &other;
	}
	else {
		ptrBigger = &other;
		ptrSmaller = this;
	}

	Sum.size = ptrBigger->size;
	Sum.current = ptrBigger->current;
	if (Sum.digits != NULL)
		delete[] Sum.digits;
	Sum.digits = new char[Sum.size];

	int tmpSmallerCurrent = ptrSmaller->current;
	int tmpDifference = ptrBigger->current - ptrSmaller->current;
	int addOne = 0;
	
	for (int i = ptrBigger->current - 1; i >= 0; i--) {
		if (tmpSmallerCurrent) {
			Sum.digits[i] = ptrBigger->digits[i] + ptrSmaller->digits[i - tmpDifference] + addOne;
			--tmpSmallerCurrent;
			if (Sum.digits[i] > 9) {
				addOne = 1;
				Sum.digits[i] = Sum.digits[i] % 10;
			}
			else
				addOne = 0;
		}
		else {
			Sum.digits[i] = ptrBigger->digits[i] + addOne;
			if (Sum.digits[i] > 9) {
				addOne = 1;
				Sum.digits[i] = Sum.digits[i] % 10;
			}
			else
				addOne = 0;
		}
	}

	if (addOne == 1) {
		for (int i = Sum.current; i > 0; i--) {
			Sum.digits[i] = Sum.digits[i - 1];
		}
		Sum.digits[0] = addOne;
		Sum.current++;
		if ((Sum.current%STARTSIZE) == 0)
			Sum.reallocSize();
	}
	return Sum;
}

void Number::reallocSize() {
		char *tmpDigits;
		int tmpSize = this->size;
		tmpDigits = new char[size];
		for (int i = 0; i < tmpSize;i++)
			tmpDigits[i] = digits[i];
		size = size + STARTSIZE;
		delete[] digits;
		digits = new char[size];
		for (int i = 0; i < tmpSize;i++)
			digits[i] = tmpDigits[i];
}

ostream& operator<<(ostream & s, const Number & p1) {
	char tmpDigit;
	for (int i = 0; i < p1.current; i++) {
		tmpDigit = p1.digits[i] + '0';
		s << tmpDigit;
	}
	return s;
}

istream& operator>>(istream & s, Number & p1){
	char tmpDig;
	p1.reallocSize();
	
	do {
		tmpDig = s.get();
		p1.digits[p1.current] = tmpDig - '0';
		if (tmpDig != '\n')
			p1.current++;
		if ((p1.current%STARTSIZE) == 0)
			p1.reallocSize();
	} while (tmpDig != '\n');

	return s;
};


Number& Number::operator*(Number& other) {
	static Number Product;
	Product.Number::~Number();

	Number tmpProduct;
	if (tmpProduct.digits != NULL)
		delete[] tmpProduct.digits;

	Number *ptrBigger, *ptrSmaller;
	if (current >= other.current) {
		ptrBigger = this;
		ptrSmaller = &other;
	}
	else {
		ptrBigger = &other;
		ptrSmaller = this;
	}


	tmpProduct.current = ptrBigger->current + ptrSmaller->current - 1;
	tmpProduct.digits = new char[tmpProduct.current];

	Product.current = ptrBigger->current + ptrSmaller->current - 1;
	//Product.size = (Product.current / 10) * 10 + 10;

	Product.digits = new char[Product.current];

	int addSome = 0;
	int multiplier = 0;

	for (int i = ptrSmaller->current - 1;i >= 0;i--) {
		for (int j = ptrBigger->current - 1;j >= 0;j--) {
			tmpProduct.digits[j-multiplier] = ptrBigger->digits[j] * ptrSmaller->digits[i] + addSome;
			if (tmpProduct.digits[j-multiplier] > 9) {
				addSome = tmpProduct.digits[j-multiplier] / 10;
				tmpProduct.digits[j-multiplier] = Product.digits[j-multiplier] % 10;
			}
			else
				addSome = 0;
		}
		Product += tmpProduct;
		++multiplier;
	}
		Product.digits[0] = addSome;

	return Product;
}


Number& Number::operator+=(Number& other) {
	Number newNumber;
	newNumber.current = this->current;
	newNumber = *this;
	*this = newNumber + other;
	return *this;
}

										//KLASA POCHODNA
derNumber& derNumber::operator=(const Number& other) {
	this->Number::operator=(other);
	return *this;
};

derNumber::derNumber() {
	//cout<< "Jestem konstruktor derNumber" << endl;
}

derNumber::~derNumber() {
	//cout << endl << "Jestem destruktor derNumber";
};

derNumber::derNumber(const derNumber& other) : Number(other) {
	//cout << endl << "Jestem konstruktor kopiujący derNumber";
};

source:

#include <iostream>
#include <cstdio>
#include "bigNumbers.h"

using namespace std;

int main() {
	
//	Number first, second;
	derNumber third, fourth, fifth;
	cin >> third;
	cin >> fourth;
	fifth = third * fourth;
	cout << "fifth: " << fifth << endl;

	system("pause");
	return 0;
}

cały kod

1

Ech...

po co ci derNumber?

void Number::reallocSize() {
        char *tmpDigits;
        int tmpSize = this->size;
        tmpDigits = new char[size];
        for (int i = 0; i < tmpSize;i++)
            tmpDigits[i] = digits[i];
        size = size + STARTSIZE;
        delete[] digits;
        digits = new char[size];
        for (int i = 0; i < tmpSize;i++)
            digits[i] = tmpDigits[i];
}

Po co kopiujesz pamięć dwa razy?

void Number::reallocSize() {
        size_t newSize = size + STARTSIZE;
        char *newDigits = new char[newSize];
        for (size_t i = 0; i < size;i++)
            newDigits[i] = digits[i];
        delete[] digits;
        digits = newDigits;
        size = newSize;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1