-2

大きな数のクラス(単一の数の無制限の長さ)のカスタム演算を書いています

AがBよりもはるかに大きい場合、複数の減分数AをBで除算することは失敗します。私は書面による除算を実装しようとしていますが、私の状況では複雑すぎます。

数値を文字列に格納できないため(プロジェクトの主な制限です)、intのリストに4桁のグループで数値を格納します。一般的な除算では4桁の構造全体が1桁のように扱ってみましたが、実装中に/演算子をオーバーロードして迷子になりました。

分割の最後の主要部分を正しく実行している場合、ヒントを取得したいですか?このクラスで分割する場合、どうすればメソッドを改善できますか?

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///
};
4

1 に答える 1

2

ここにも疑問符のない質問があると思います。

2つの複雑なタスクを同時に解決しようとします(これはおそらく失敗します-またはすでに失敗しています)。これらの2つのタスクを分割します。

  • フリーストアのリストアイテムを安全に管理します(std::listまたはstd::vectorを使用します。そうでない場合は、演習目的でのみ使用してください)
  • 多倍長算術演算を行う(特に、学校で学んだとしても除算は複雑です)

「4バイト桁」を格納するには、std::vectorの方が適しているようです。リストノードに格納する場合、8バイト以上ではなく、数値ごとに4バイトを使用します。std :: vectorは、数値が大きくなると(a + = b)大きくなり、必要に応じて小さくなります。

算術演算では、プラス/マイナス記号を分離して、最初に非負の数を操作することもできます。

足し算、引き算、掛け算は比較的簡単です。部門については、ドナルド・クヌースの「The Art of ComputerProgramming」Vol.2(半数値アルゴリズム)を調べなければならず、それを理解するのに2週間かかりました。たぶん、私はこの時点では特に得意ではありません。

2バイトの数値を乗算すると4バイトの数値が得られることを考慮に入れてください。そうしないと、整数のオーバーフローによって結果が台無しになります。その逆は、数値を分割することです。

同じ教育タスクでの私の結果を確認したい場合は、私の名前と「Ganzzahl」をグーグルで検索してください。しかし、注意してください、それはドイツ語で書かれた、十分にテストされていません、そして私が数年前に書いたので、私はそれがもううまく書かれたコードであるとは思いません...

プロダクションコードソリューションを探す場合は、代わりにGNUmultiprecisionintegerなどのライブラリを入手してみてください。

于 2011-06-28T21:53:58.210 に答える