漫长的算术

时间:2016-03-02 04:09:38

标签: delete-file

与它们做点什么

他们要求添加一些东西 因为看起来我的帖子主要是代码。 我希望这已经足够了。

无法删除它。

    Solong sum;
    sum = 0;
    for (int i = 0; i != 10; ++i) {
        if ((i != 0) && (i != 8)) {
            sum = sum + n2[i];
        }
    }
    std::cout << sum;
    std::cout << std::endl;
}

2 个答案:

答案 0 :(得分:3)

这些问题让我看到了你的代码 - 所以我可能错过了一些不太明显的东西。

operator = (const int & b),忽略参数的值,只使低位字为零。所以我想你想要number[0] = b;。您还需要更新size。当b溢出你的基数时,你应该也可以处理这种情况,设置size并填充更高阶的单词。

operator +中,检测到基数位溢出并设置进位标志,但结果的位数永远不会被进位表示的值减少到下一位数:

if (res.number[i] >= res.radix) {
    overDecimal = 1;
}

所以这需要像res.number[i] -= res.radix这样的东西 此外,当一个参数的size小于另一个参数时,使用超出其size的高阶词。赋值运算符并不打算确保将高于size的高阶词设置为零,因此您需要确保在其他任何地方将它们设置为零,或者忽略这些非零高值 - 订购此功能中的单词。

void operator <<的循环中,您的索引i从最后一个元素开始,但是通过递增来更新:

    for (int i=a.size-1; ...; ++i) { ...

所以我猜这需要改为--i

其他一些问题:

两个operator = (...都应该返回Solong&而不是void,最后会返回return *this;

operator << (std::ostream& out, const Solong &a)应该返回std::ostream&而非void,最后返回return out;

答案 1 :(得分:0)

首先:您的程序在此功能中导致分段错误:

  > void operator << (std::ostream& out, const Solong &a) {
  >     for (int i = a.size - 1; i != -1 || (i != a.size - 1 && a.number[a.size - 1] == 0); ++i) {
x >        out << a.number[i];
  >     }
  > }

您可以使用调试器找到此行。在Linux上,您可能想要使用gdb。如果您正在使用某些IDE,则应将其集成在那里。我不确定你想在这个功能中做什么。也许你可以写这个?

for (int i = a.size - 1; i >= 0; --i) out << a.number[i];

更改此程序后程序不再崩溃。我为-1087373312得到了42但您在应用程序中有未定义的行为。每次运行时我都会得到另一个结果。现在我将展示一些我会改变的其他事情。这样做之后它对我有用:

我会使用std :: vector来存储数字。此容器将保留您的大小,您可以使用resize

进行更改
class Solong {
private:
    int radix = 10;
    std::vector<int> number;

我必须更改构造函数:

public:
    Solong() :
        number(1, 1) // are you shure you want initialize it with 1 instead of 0?
    {}

您可能还希望有一个构造函数来设置初始值。

    Solong(const int &value)
    {
        *this = value;
    }

operator<<可以返回对out的引用:

    friend Solong operator+ (const Solong &a, const Solong &b);
    friend std::ostream &operator<< (std::ostream &out, const Solong &a);

由于我不再使用此类中的数组,我可以使用operator=(const Solong &b)的隐式定义。我只想从类中删除operator=(const Solong &b)的自定义定义。

我认为您希望在b函数中将number分配给0而不是operator=(const int &b)。您也应该返回对象本身的引用。由于每int只允许 0-9 ,因此您也必须确保这一点。

    void operator= (int b) {
        this->number.clear();
        while (b > 0) {
            this->number.push_back(b % radix);
            b = b / radix;
        }
    }
};

对于operator+,有很多事情:

  • 我现在必须使用resize number
  • 如果要将定义放在头文件中,则必须指定inline
  • 条件|| overDecimal对我来说似乎不对,因为它们会导致分段错误。
  • 在阅读此值之前,您必须先检查a.number[i]b.number[i]是否有效。
  • 如果有溢出,你应该更改res.number [i]

这是我更新的实施:

inline Solong operator+ (const Solong &a, const Solong &b) {
    Solong res;
    res.number.resize(std::max(a.number.size(), b.number.size()));
    int overDecimal = 0;
    for (std::size_t i = 0; i < res.number.size(); ++i) {
        int aDigit = (a.number.size() > i ? a.number[i] : 0);
        int bDigit = (b.number.size() > i ? b.number[i] : 0);
        res.number[i] = aDigit + bDigit + overDecimal;
        overDecimal = 0;
        if (res.number[i] >= res.radix) {
            overDecimal = 1;
            res.number[i] = res.number[i] % res.radix;
        }
    }
    if (overDecimal)
        res.number.push_back(overDecimal);
    return res;
}

最后我修改了operator<<,如上所述,添加了关键字inline并返回对out的引用:

inline std::ostream &operator<< (std::ostream &out, const &a) {
    for (int i = a.number.size() - 1; i >= 0; --i) {
        out << a.number[i];
    }
    return out;
}

我还会将i更改为std::size_t并将int的整个大小用于一位数。不仅仅是int的10个值。然后我会将overDecimal的名称更改为cource的overflowedDigit,因为不再有十进制。你还应该考虑到你现在不支持负数。但所有这些都会增加一些复杂性,我现在不想描述它。