任意精度无符号整数,仅支持后递增运算符
Arbitrary precision unsigned integer supporting just post increment operator
我正在寻找一个非常简单的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;
}
<小时 />任意精度算术解释中的一些提示和技巧:
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;
}
该代码实现了通常称为二进制编码十进制 (BCD) 的内容。非常简单,而且,正如您所说,如果您只想递增而不需要一般添加,则实现可以简单得多。为了进一步简化,请使用'0'
到'9'
的数字的内部字符表示形式,而不是通过9
0
的值。为了进一步简化,将字符存储在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');
这使得流插入器几乎微不足道。
相关文章:
- 编译时未启用intel oneApi CUDA支持
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 基于 SFINAE 的特征,用于确定是否支持运算符 +
- 重载C++中的[]运算符以支持自定义设置函数
- 支持宏中的<<运算符
- 什么是编程语言支持定义您自己的自定义运算符?
- C# 运算符重载是否支持类似C++"+="?
- 防止为字符串流提取运算符不支持的类型实例化模板类 (>>)
- 为什么作用域枚举默认支持运算符'<'?
- 在地图迭代器上不支持非仿制地图上的平等运算符(==)
- 如何解决Visual Studio 2012不支持显式转换运算符的问题
- 如何在boost::精神计算器中添加对指数运算符的支持
- 任意精度无符号整数,仅支持后递增运算符
- 为什么std::ratio不支持比较运算符
- 在 c++ 中,条件运算符不支持指针
- 使用 GDB 的 Python 漂亮打印不支持地图的索引运算符 []
- 运算符支持哪些格式>>用于 boost::chrono::d uration?
- 在const 2D数组上支持my_2D_Array[x][y](双运算符[]);无法使事情正常工作
- 为什么在这种情况下不调用赋值运算符以支持复制构造函数