我正在寻找一个非常简单的 C++ 类,它实现了一个具有任意精度的无符号整数和后递增运算符。
我知道有用于任意精度整数运算的库,但我的需求非常简单,我更愿意避免整个库的重量。
看来我现在的实现还是不够简单,不够优雅。你有什么建议?
#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;
}
最佳答案
为了避免返回变异值,保存一个本地拷贝并返回它:
UNat operator++(int)
{
UNat copy = *this;
// ....
return copy;
} // don't return by reference
相比之下,前缀运算符确实通过引用返回。
UNat& operator++ ()
{
// ....
return *this;
}
来自 Arbitrary-precision arithmetic Explanation 的一些提示和技巧:
1/ When adding or multiplying numbers, pre-allocate the maximum space needed then reduce later if you find it's too much. For example, adding two 100-"digit" (where digit is an int) numbers will never give you more than 101 digits. Multiply a 12-digit number by a 3 digit number will never generate more than 15 digits (add the digit counts).
加法函数的替代实现如下所示:
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++ - 任意精度无符号整数仅支持后递增运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20719376/