假设你有一个很长的二进制字(> 64bit),它代表一个无符号整数值,你想打印实际的数字。我们正在谈论C ++,所以让我们假设您从 bool [] 或 std :: vector< bool> 或 std :: bitset ,并以 std :: string 或某种 std :: ostream 结束 - 无论您的解决方案更喜欢什么。但请只使用核心语言和STL。
现在,我怀疑,你必须对它进行评估,以获得一些中间结果,这些结果足够小以便存储 - 最好是基数10,如x·10 k 。我可以想出从那一点汇总数字。但由于没有对应于10的基数的块宽,我不知道该怎么做。当然,你可以从任何其他的块宽开始,比方说3,以x·(2 3 ) k 的形式得到中间体,然后转换它以10为基数,但这将导致x·10 3·k·lg2 显然有一个浮点指数,这没有任何帮助。
无论如何,我已经厌倦了这个数学废话,我很感激一个深思熟虑的建议。
您诚挚的,
阿明
答案 0 :(得分:1)
我将假设你已经有了某种bignum除法/模数函数,因为实现这样的事情是一个彻头彻尾的噩梦。
class bignum {
public:
bignum(unsigned value=0);
bignum(const bignum& rhs);
bignum(bignum&& rhs);
void divide(const bignum& denominator, bignum& out_modulo);
explicit operator bool();
explicit operator unsigned();
};
std::ostream& operator<<(std::ostream& out, bignum value) {
std::string backwards;
bignum remainder;
do {
value.divide(10, remainder);
backwards.push_back(unsigned(remainder)+'0');
}while(value);
std::copy(backwards.rbegin(), backwards.rend(), std::ostream_iterator(out));
return out;
}
如果舍入是一个选项,那么将大多数bignums转换为double
也应该是相当简单的,这将是 LOT 更快。即,将64个最高有效位复制到unsigned long
,将其转换为double
,然后乘以2.0,得到有效位数减去64的幂。(我说有效位,因为你必须跳过任何前导零)
因此,如果您有150个有效位,请将前64位复制为unsigned long
,将其转换为double
,然后将其乘以std::pow(2.0, 150-64)
~7.73e + 25以获得结果。如果你只有40个有效位,在右边填充零,它仍然有效。将40位复制到unsigned long
的MSB,将其转换为double
,然后乘以std::pow(2.0, 40-64)
~5.96e-8得到结果!
Oli Charlesworth在Double Dabble上发布了维基百科页面的链接,该链接打破了我在水中展示的第一个算法。我不觉得傻。