大整数增加,我知道理论..在实践中仍然生锈
Big Integer addition, I know the theory... still rusty in practice
所以,我正在尝试构建一个简单的大整数类,我在互联网上阅读了一些页面,但是我很困惑。我知道这个理论,我知道我需要一个携带,但是我见过的所有例子,它们都集中在炭中,而在基本10中,我使用的是另一种方法来使其更快一些。我将感谢对加分配运营商的一些帮助,其余的我将尝试自己弄清楚。
#include <iostream>
#include <string>
#include <vector>
using std::cout;
using std::endl;
class big_integer {
using box = std::vector<int unsigned>;
box data {0};
box split(std::string const & p_input) const {
box output;
for (size_t i {}; i < p_input.size(); i += 8) {
output.push_back(stoi(p_input.substr(i, 8)));
}
return output;
}
public:
big_integer(std::string const & p_data)
: data {split(p_data)}
{}
big_integer(int unsigned const p_data)
: data {p_data}
{}
big_integer & operator +=(big_integer const & p_input) {
int carry {};
for (size_t i {}; i < data.size(); ++i) {
//Need help here!
//All examples I see either use primitive arrays
//or are too esoteric for me to understand.
//data[i] += p_input.data[i] + carry;
}
return *this;
}
std::string to_string() const {
std::string output;
output.reserve(data.size() * 8);
for (auto const i : data) {
output.append(std::to_string(i));
}
return output;
}
};
std::ostream & operator <<(std::ostream & p_output, big_integer const & p_input) {
return p_output << p_input.to_string();
}
int main() {
big_integer test1 {"126355316523"};
big_integer test2 {255};
test1 += test1;
cout << test1 << endl;
cout << test2 << endl;
return 0;
}
正确。因此,基本问题是如何进行unsigned + unsigned + carry
以提供unsigned
和carry
。如果我们考虑16位整数(在32位中使用相同,但更键入),则在第一个数字上,0xffff 0xffff == 0xfffe a随身携带1.0xffff 随身携带。因此,携带只能是一个。该算法是:
unsigned lhs, rhs, carry_in; // Input
unsigned sum, carry_out; // Output
sum = lhs + rhs;
carry_out = sum < lhs ;
sum += carry_in;
carry_out = carry_out || sum < lhs;
基本上,这个想法是在unsigned
中进行添加,然后检测包装(因此随身携带)。非常烦人的是,这是大量有条件的逻辑和多个指令"随身携带",这是我使用过的每个说明集中的指令。(注意:可能值得进行carry_out
的最终计算使用|
而不是||
-它保存分支,这对性能不利。与往常一样,配置文件查看是否有帮助。)
如果您最终要支持乘法,则需要一种类型,该类型的宽度是您的"数字"的两倍 - 在这种情况下,您也可以使用它来添加。使用上面的变量,假设"无签名的长长"是您的"宽"类型:
const auto temp = (unsigned long long)lhs + rhs + carry_in;
sum = temp; // Will truncate.
carry_out = temp > UINT_MAX;
选择您的"宽"类型可能很棘手。作为第一次通过,最好将uint32_t
用于数字,而uint64_t
则用于您的宽类型。
有关实施多工算术的更多详细信息,《应用加密手册》第14章看起来很有用。
相关文章:
- <random>在实践中应该实际使用哪个随机数引擎? std::mt19937?
- std::is_convertible 和 std::convertible_to 之间的区别(在实践中)?
- 在实践中,在运行时为零的乘法中是否有任何"lazy"评估
- P1008("prohibit aggregates with user-declared constructors")在实践中什么时候有用?
- 无锁原子在实践中是无地址的
- clang的"-Ofast"选项在实践中有什么作用,特别是对于与gcc的任何差异?
- 是在实践中有用的释放序列的概念
- 在现代C 不良实践中,原始指针的使用是
- 大整数增加,我知道理论..在实践中仍然生锈
- 为什么在实践中向右移动在霓虹灯和SSE中向左移动(反之亦然)
- 在实践中,无序映射真的比映射快吗
- 标准库在实践中如何实现哈希表
- c++最佳实践中的矩阵创建-销毁
- c在c++实践中的应用
- 如何在实践中解决项目编译中链接库的顺序问题
- 通过使用两个凸壳的切线来合并它们的算法在实践中是如何工作的
- 是在实践中真正使用的PIMPL习语
- 非公共C++继承在实践中的使用频率
- c++函数中理论上可以作为形参传递多少个实参
- Google的Protocol Buffer在实践中对浮点类型的处理有多跨平台?