-2

我正在为大数字类编写自定义算术(单个数字的无限长度)

当 A 比 B 大得多时,使用多个递减数 A 除以 B 失败。我正在尝试实现书面除法,但我发现它在我的情况下太复杂了。

我不能将数字存储在字符串中(这是项目的主要限制),所以我将它们存储在 int 列表中的 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///
};
4

1 回答 1

2

我想这里有一个问题,也没有问号。

您尝试同时解决两个复杂的任务(这可能会失败 - 或者已经失败)。拆分这两个任务:

  • 安全地管理免费商店中的列表项(使用 std::list 或 std::vector;如果不这样做,仅用于锻炼目的)
  • 做多精度算术运算(尤其是除法很复杂,即使我们在学校学过)

对于存储“4 字节数字”,std::vector 似乎更好。当将它们存储在列表节点中时,每个数字使用 4 个字节而不是 8 个或更多字节。当数字变大(a += b)时,std::vector 可以增长,如果需要,可以缩小。

对于算术,您还可以将加号/减号分开并首先对非负数进行运算。

加法、减法和乘法相对简单。对于除法,我必须查看 Donald Knuth 的“计算机编程艺术”第 2 卷(半数字算法)并有两周的时间来弄清楚。也许我在这一点上不是特别好。

考虑到,当乘以 2 个字节数时,您会得到 4 个字节数。否则整数溢出会破坏你的结果。另一种方法是除数。

如果您想查看我在同一教育任务中的结果,请在 Google 上搜索我的姓氏和“Ganzzahl”。但是请注意,它没有经过大量测试,是用德语编写的,而且自从我几年前编写以来,我不再认为它写得很好......

如果您正在寻找生产代码解决方案,请尝试使用诸如 GNU 多精度整数之类的库。

于 2011-06-28T21:53:58.210 回答