-2

I'm writing a custom arithmetics for a big numbers class (unlimited lenghth of a single number)

Dividing using multiple decrementing numer A by B fails when A is much grater than B. I'm trying to implement written division, but i find it too complicated in my situation.

I can't store numbers in string (it is the main limitation of the project), so i store them in groups of 4 digits in a list of int's. I tried to treat it like the whole 4 digit structure is a single digit in popular written division, but i got lost during implementing, by overloading / operator.

I'd like to get a hint if I'm doing the last, main part of dividing correct? How can I improve the method if dividing in this class?

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///
};
Chris
  • 5
  • 3
  • 2
    Is there a question here, or even a statement of problem?? – Blazes Jun 28 '11 at 20:41
  • +1 @Blazes. If there's no '?', it's not a question. – Carl Norum Jun 28 '11 at 20:42
  • Without answering your "question", one problem with your code is the way you return things: every `new` allocates space on the heap, which is never freed again! Memory leak. `operator/` must return by value. – leftaroundabout Jun 28 '11 at 20:45
  • Sorry, for not specyfying why i'm writing. I'm very tired already, thats the reason. I now that i have memory leaks - flushing will be done at the end. I'd like to get a hint if I'm doing the last, main part of dividing correct? How can I improve the method if dividing in this class? – Chris Jun 28 '11 at 20:51
  • It's really hard to tell, I don't understand how this is supposed to work. Could you add some comments on what variable means what? – leftaroundabout Jun 28 '11 at 21:23
  • maybe you should use a more common language for your comments? English would be a good start, thx – Thomas Berger Jun 28 '11 at 22:13

1 Answers1

2

I suppose there is a question in here, also without a question mark.

You try to solve two complicated tasks at the same time (this will probably fail - or has failed already). Split these two tasks:

  • manage list items in free store safely (use std::list or std::vector; if you don't, for exercising purposes only)
  • do multiprecision arithmetic operations (especially division is complicated, even when we learned it in school)

For storing the "4-byte-digits" a std::vector seems to be better. It uses 4 bytes per number instead for 8 or more, when storing them in list nodes. A std::vector can grow, when numbers get bigger (a += b) and shrink, if needed.

For arithmetic you can also separate the plus/minus sign and operate on non-negative numbers first.

Adding, subtracting and multiplying are relatively straight forward. For division I had to look on Donald Knuth's "The Art of Computer Programming" Vol.2 (seminumerical algorithms) and had two weeks to figure it out. Maybe I'm not especially good at this point.

Take into account, that you get 4 byte numbers when multiplying 2 byte numbers. Otherwise integer overflow will ruin your results. The other way around it is for dividing numbers.

If you want to look at my results on the same educational task, google for my last name and "Ganzzahl". But beware, it's not heavily tested, written in German, and since I wrote some years ago, I don't consider it well written code anymore...

If you look for a production code solution, try to get to some library like GNU multi precision integer instead.

René Richter
  • 3,839
  • 3
  • 34
  • 42