Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
支持仅后增量运算符的任意精度无符号整数 < >我寻找一个非常简单的C++类,它实现了一个具有任意精度的无符号整数,只是一个后增量运算符。_C++_Arbitrary Precision - Fatal编程技术网

支持仅后增量运算符的任意精度无符号整数 < >我寻找一个非常简单的C++类,它实现了一个具有任意精度的无符号整数,只是一个后增量运算符。

支持仅后增量运算符的任意精度无符号整数 < >我寻找一个非常简单的C++类,它实现了一个具有任意精度的无符号整数,只是一个后增量运算符。,c++,arbitrary-precision,C++,Arbitrary Precision,我知道有用于任意精度整数运算的库,但我的需求非常简单,我更喜欢避免一个完整库的重量 在我看来,我当前的实现仍然不够简单,不够优雅。你有什么建议 #include <vector> #include <string> #include <algorithm> class UNat { public: static const char base = 10; UNat( const char* n ) { std::str

我知道有用于任意精度整数运算的库,但我的需求非常简单,我更喜欢避免一个完整库的重量

在我看来,我当前的实现仍然不够简单,不够优雅。你有什么建议

#include <vector>
#include <string>
#include <algorithm>

class UNat
{
public:
    static const char base = 10;
    UNat( const char* n )
    {
        std::string s(n);
        std::reverse(s.begin(),s.end());
        for ( size_t i = 0; i < s.length(); i++ ) {
            n_.push_back(s[i]-'0');
        }
    }

    UNat& operator++(int) 
    {
        bool carry = false;
        bool finished = false;

        for ( size_t i = 0; i < n_.size() && !finished; i++ ) {
            n_[i] = add(n_[i],1,carry);
            if ( carry ) {
                finished = false;
            } else {
                finished = true;
            }
        }
        if ( carry ) {
            n_.push_back(1);
        }
        return *this;
    }

    std::string to_string() const
    {
        std::string r(n_.begin(), n_.end());
        std::reverse(r.begin(),r.end());
        std::for_each(r.begin(), r.end(), [](char& d) { d+='0';});
        return r;
    }

private:
    char add( const char& a, const char& b, bool& carry )
    {
        char cc = a + b;
        if ( cc >= base ) {
            carry = true;
            cc -= base;
        } else {
            carry = false;
        }
        return cc;
    }
    std::vector< char > n_;    
};

std::ostream& operator<<(std::ostream& oss, const UNat& n)
{
    oss << n.to_string();
    return oss;
}

#include <iostream>

int main()
{
    UNat n("0");
    std::cout << n++ << "\n";
    std::cout << UNat("9")++ << "\n";
    std::cout << UNat("99")++ << "\n";
    std::cout << UNat("19")++ << "\n";
    std::cout << UNat("29")++ << "\n";
    std::cout << UNat("39")++ << "\n";
    return 0;
}
#包括
#包括
#包括
无人值守舱
{
公众:
静态常量字符基=10;
UNat(常量字符*n)
{
std::字符串s(n);
std::reverse(s.begin(),s.end());
对于(大小i=0;i=base){
进位=真;
cc-=基础;
}否则{
进位=假;
}
返回cc;
}
标准::向量n;
};

std::ostream&operator为了避免返回变异值,请保存本地副本并返回:

UNat operator++(int) 
{
    UNat copy = *this;
    // ....
    return copy;
} // don't return by reference
相对而言,前缀运算符通过引用返回

UNat& operator++ ()
{
  // ....
  return *this;
}

以下是一些提示和技巧:

1/当数字相加或相乘时,预先分配最大空间 如果你觉得太多的话,需要减少。例如 加上两个100位数字(其中数字是一个整数)永远不会给出结果 您可以输入超过101个数字。将12位数乘以3位数 数字生成的数字永远不会超过15位(加上数字计数)

加法函数的替代实现如下所示:

c->lastdigit = std::max(a->lastdigit, b->lastdigit)+1;
carry = 0;

for (i=0; i<=(c->lastdigit); i++) {
    c->digits[i] = (char) (carry+a->digits[i]+b->digits[i]) % 10;
    carry = (carry + a->digits[i] + b->digits[i]) / 10;
}
c->lastdigit=std::max(a->lastdigit,b->lastdigit)+1;
进位=0;
对于(i=0;ilastdigit);(i++){
c->数字[i]=(字符)(进位+a->数字[i]+b->数字[i])%10;
进位=(进位+a->数字[i]+b->数字[i])/10;
}

该代码实现了通常所说的二进制编码十进制(BCD)。非常简单,而且,正如您所说,如果您只想增量,而不需要一般的添加,那么实现可以简单得多。为了进一步简化,请使用数字
'0'
'9'
的内部字符表示,而不是值
0
9
。为了另一种简化,将字符存储在
std::string

for (int index = 0; index < digits.size(); ++index) {
    if (digits[index] != '9') {
        ++digits[index];
        break;
    }
    digits[index] = '0';
}
if (index == digits.size())
    digits.push_back('1');
for(int index=0;index

这使得流插入器几乎变得微不足道。

Post increment应该增加值并生成原始值作为表达式结果。似乎您的后增量运算符会生成修改后的值。这就是你需要帮助的问题吗?我想如果你所做的只是增量,ripple carry也没那么糟糕。。。在32位或64位原语而不是8位原语上进行操作可能很好,但8位确实保持了它的简单性。@ebyrob:我从未找到巴贝奇预测方案的良好描述,但帕斯卡(在他之前)使用了一个很好的重力辅助方案。基本上,在加法之前,每个数字轮都必须用手涂底漆。然后,任何一次搬运都会在下一个数字轮上投掷一些东西,给它一个额外的小推力,这些投掷动作可以并行进行。显然是巧妙的。但我不明白它怎么能取消测序(如果你想做的是增加它,你就不需要无限的精确性。在每增加1ns,一个64位的长将至少占用10秒9秒。然后你可以使用C++长和标准的后增量运算符。@ IRA:<代码>长< /C>只有32个比特,所以<代码>长Lo/<代码>会更像它。如果你想要的话。要使用不同的半径,可以在当前位值上使用binary和just以及if-then-else。但这只是制作一个缓慢版本的无限精度。@IraBaxter-可以添加很多钟和口哨。问题是如何使它变得简单,这是我所能看到的最简单的。特别是,支持大于10的基数意味着编写复杂得多的代码来增加单个元素。支持大于10的半径是很简单的。对于基数r,使用值为0到r-1的数字。if语句变成“digits[index]!=”。如果选择r=10^n(选择n=1)然后打印数字就很容易了。@IraBaxter-如果你这样做,流插入器就会变得更复杂;它不能再简单地复制现有的字符值。再说一遍:有很多东西可以以更复杂的代价添加。我的目标是最简单的,而不仅仅是简单的。如果你有其他目标,一定要给出你自己的答案@高度权威的网站Yakk不同意。它区分未压缩的BCD和压缩的BCD。