c++ primer 16.41:编写一个新的 sum 版本, 它的返回类型保证足够大,足以容纳加法结果
这道题的难点不是模板,而是C++如何处理超大数。示例中,当一个数位数太大,编译器就不可识别了,比如45位的123456789123456789123456789123456789123456789。
不要说加,就是储存都是个问题。会转为2^128-1这么个数。其实这也是天文数字了。奈何还会出问题。在windows mingw64 下,也没有可输出重载符号"<<"。
莫不是要重新撸个超大数类?转换存储输出,不是问题,计算是个问题,数学不好就不要挑战了。所以还是不要造轮子了,直接找库,例如boost高精度库。<boost/multiprecision/cpp_int.hpp> 确实比较占空间,至于要不要用,随你吧。
因为没有找到直接将一个巨大数转换成cpp_int类,只好通过函数通过string进行转换。如果要处理巨大数,比如加密动辄256位什么的,可以考虑。这个类有int1024_t,二的一千多次方,但不止这么大,通过定义模板实参类型,可以近乎无限扩大,比如我就实现了一个uint2048_t ,应该够用了。
using uint2048_t =
boost::multiprecision::number<
boost::multiprecision::cpp_int_backend<
2048, 2048, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using LLint = uint2048_t;
using Lint = boost::multiprecision::int1024_t;
#include <string>
#include <boost/multiprecision/cpp_int.hpp>
#include "bigint.h"
using namespace std;
template <typename T, typename S>
auto sum(T a, S b) -> decltype(a + b)
{
return a + b;
}
int main()
{
auto i = sum(4, 0.2);
auto j = sum(123456789123456789123456789123456789123456789, 123456789123456789123456789123456789123456789);
auto k = sum(bigint::stoLint("123456789123456789123456789123456789123456789"), bigint::stoLint("123456789123456789123456789123456789123456789"));
std::cout << i << std::endl;
std::cout << j << std::endl;
std::cout << k << std::endl;
return 0;
}
|