2011-06-28 4 views
-2

J'écris un Arithmétique personnalisés pour une grande classe de nombres (lenghth illimité d'un seul numéro)un problème de division dans la coutume grand nombre de classe (C++)

division à l'aide de multiples décrémentation numer A par B échoue lorsque A est J'essaie de mettre en place une division écrite, mais je trouve que c'est trop compliqué dans ma situation.

Je ne peux pas stocker de nombres dans une chaîne (c'est la principale limitation du projet), donc je les stocke dans des groupes de 4 chiffres dans une liste d'int. J'ai essayé de le traiter comme toute la structure à 4 chiffres est un seul chiffre dans la division écrite populaire, mais je me suis perdu lors de la mise en œuvre, en surcharge/opérateur.

Je voudrais obtenir un indice si je fais la dernière, la partie principale de la division correcte? Comment puis-je améliorer la méthode si je divise dans cette classe?

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/// 
}; 
+2

Y at-il une question ici, ou même une déclaration de problème ?? – Blazes

+0

+1 @Blazes. S'il n'y a pas de '?', Ce n'est pas une question. –

+0

Sans répondre à votre "question", un problème avec votre code est la façon dont vous retournez les choses: chaque 'new' alloue de l'espace sur le tas, qui n'est jamais libéré! Fuite de mémoire. 'operator /' doit retourner par valeur. – leftaroundabout

Répondre

2

Je suppose qu'il y a une question ici, également sans un point d'interrogation.

Vous essayez de résoudre deux tâches complexes en même temps (cela échouera probablement - ou a déjà échoué). Divisez ces deux tâches:

  • gérer les éléments de liste en magasin libre en toute sécurité (utilisation std :: liste ou std :: vecteur, si vous ne le faites pas, pour l'exercice à titre indicatif seulement)
  • multiprécision opérations arithmétiques ne pas (en particulier la division est compliquée, même lorsque nous l'avons appris à l'école)

Pour stocker les "4-byte-digits", un vecteur std :: semble être meilleur. Il utilise 4 octets par nombre à la place pour 8 ou plus, en les stockant dans des nœuds de liste. Un vecteur std :: peut croître, quand les nombres deviennent plus grands (a + = b) et rétrécit, si nécessaire. Pour l'arithmétique, vous pouvez également séparer le signe plus/moins et opérer d'abord sur les nombres non négatifs.

L'addition, la soustraction et la multiplication sont relativement simples. Pour la division, j'ai dû regarder sur "L'art de la programmation informatique" Vol.2 (algorithmes seminumerical) de Donald Knuth et avait deux semaines pour le comprendre. Peut-être que je ne suis pas particulièrement bon à ce stade. Prenez en compte que vous obtenez des nombres de 4 octets en multipliant les nombres de 2 octets. Sinon, un dépassement d'entier va gâcher vos résultats. L'inverse est pour diviser les nombres.

Si vous voulez regarder mes résultats sur la même tâche éducative, google pour mon nom de famille et "Ganzzahl". Mais attention, il n'est pas lourdement testé, écrit en allemand, et depuis que j'ai écrit il y a quelques années, je ne considère plus le code bien écrit ...

Si vous cherchez une solution de code de production, essayez de vous rendre à une bibliothèque comme l'entier GNU multi précision à la place.

Questions connexes