Проблема с делением в пользовательском классе больших чисел (C ++) - PullRequest
0 голосов
/ 29 июня 2011

Я пишу пользовательскую арифметику для класса больших чисел (неограниченная длина одного числа)

Деление с использованием кратного убывающего числа A на B завершается неудачно, когда A намного больше, чем B. Я пытаюсь реализовать письменное деление, но я нахожу это слишком сложным в моей ситуации.

Я не могу хранить числа в строке (это основное ограничение проекта), поэтому я храню их в группах по 4 цифры в списке целых чисел. Я пытался трактовать это так, как будто вся структура из 4 цифр является одной цифрой в популярном письменном делении, но я потерял во время реализации из-за перегрузки / оператора.

Я хотел бы получить подсказку, если я делаю последнюю, основную часть правильного деления? Как я могу улучшить метод, если делить в этом классе?

struct Node{
    int value;
    Node* next,*prev;
};

class number {

public:

Node* head;

number();   //konstruktor domyślny
~number();  //destruktor
void addNode(string str); //dodanie nowego wezla na poczatek liczby
void addNode(int str); //dodanie nowego wezla na poczatek liczby (z wartosci int)
number& operator+(number& licz); //operator dodawania
number& operator-(number& licz); //operator odejmowania
bool operator>(number& licz); //operator porównania (czy a > b)
bool operator<(number& licz); //operator porównania (a mniejsze od b)
bool operator==(number&  licz); //operator porównania (czy a równe b)
number& operator=(const number& licz); //operator przypisania
number& operator-(); //operator zamiany liczby na przeciwną
friend istream& operator>>(istream& input,number& li);  //operator pobierania liczby
friend ostream& operator<<(ostream& s,number& li); //operator wypisania
void validate(); //funkcja usuwajaca zera z poczatku liczby
number& operator/(number& licz);  //dzielenie calkowitoliczbowe
number& operator*(number& licz); //mnożenie
void pushNode(int str);

};

number& number::operator/(number& licz)
{
/////////cases of dividing//////

if (this->head->value<0 && licz.head->value<0) {
    return (-(*this))/(-licz);
}
if (this->head->value<0 && licz.head->value>0) {
    return -((-(*this))/licz);
}
if (this->head->value>0 && licz.head->value<0) {
    return -(*this/(-licz));
}

number tmp_this=*this;
number tmp_licz=licz;
number zero;
zero.addNode(0);

//dividing by zero//
if (licz==zero) {
    cout<<"dividing by zero"<<endl;  
    number* t=new number;
    t->addNode(0);
    return *t;
}

//dividing zero by sth ///
if (*this==zero) {
    number* t=new number;
    t->addNode(0);
    return *t;
}

number i,jeden;
i.addNode(0);
jeden.addNode(1);

if (licz == jeden) {
    return *this;
}

/// here real mess start///
string pl="";

number* tmp=new number;
Node* p=this->head,*q=licz.head;
tmp->pushNode(q->value);
while (p && *tmp  < licz) {
    p=p->next;
    tmp->pushNode(p->value);
}
number* wynik=new number;
wynik=tmp;
int j;
while (*wynik > zero || *wynik==zero) {
    *wynik=*wynik-tmp_licz;
    j++;
}
char* str;
sprintf(str, "%d", j);

///end od mess///
};

1 Ответ

2 голосов
/ 29 июня 2011

Полагаю, здесь есть вопрос, также без знака вопроса.

Вы пытаетесь решить две сложные задачи одновременно (это, вероятно, не удастся - или уже провалилось). Разделите эти две задачи:

  • безопасное управление элементами списка в бесплатном хранилище (используйте std :: list или std :: vector; если нет, только для ознакомительных целей)
  • выполнять многоточные арифметические операции (особенно сложное деление, даже когда мы изучали его в школе)

Для хранения "4-байтовых цифр" лучше использовать std :: vector. Он использует 4 байта на число вместо 8 или более при хранении их в узлах списка. Std :: vector может расти, когда числа увеличиваются (a + = b) и уменьшаются, если это необходимо.

Для арифметики вы также можете отделить знак плюс / минус и оперировать неотрицательными числами в первую очередь.

Сложение, вычитание и умножение относительно просты. Для разделения я должен был посмотреть на «Искусство компьютерного программирования» Тома Дональда Кнута (том 2), и у меня было две недели, чтобы понять это. Может быть, я не особенно хорош в этом моменте.

Примите во внимание, что вы получаете 4-байтовые числа при умножении 2-х байтовых чисел. В противном случае целочисленное переполнение испортит ваши результаты. И наоборот, для деления чисел.

Если вы хотите посмотреть мои результаты по одному и тому же учебному заданию, поищите мою фамилию в Google и "Ganzzahl". Но будьте осторожны, он не сильно протестирован, написан на немецком языке, и поскольку я написал несколько лет назад, я больше не считаю его хорошо написанным кодом ...

Если вы ищете решение для производственного кода, попробуйте перейти к некоторой библиотеке, такой как GNU multi точность integer.

...