二进制到十进制的基移
我需要一种将任意大小的无符号整数(以二进制格式存储)转换为十进制的算法。即使其易于阅读;)
我目前使用可能(或显然)有点幼稚的方式通过除以十来连续计算模数和余数。
不幸的是速度有点……蹩脚。
例如 我计算 2000^4000(使用我的 bignum 库)大约需要 1.5 秒(请不要着火 xD)。然而,包括必要的基本转换在内的打印需要大约 15 分钟,这非常烦人。
我已经测试过 bc,它在不到一秒的时间内完成了这两项操作。
它是如何做到的? (不是 fft 的乘法以及任何基本转换)
I need an algorithm that converts an arbitrarily sized unsigned integer (which is stored in binary format) to a decimal one. i.e. to make it human-readable ;)
I currently use the maybe (or obviously) somewhat naive way of continuously calculating the modulus and remainder through division through ten.
Unfortunately the speed is somewhat... lame.
e.g.
I calculate 2000^4000 (with my bignum library) which takes roughly 1.5 seconds (no flaming please xD). The print including the necessary base conversion however takes about 15 minutes which is quite annoying.
I have tested bc which does both in a lot less than one second.
How does it do that? (Not the multiplication stuff with ffts and whatever only the base conversion)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我目前使用可能(或显然)有点幼稚的方式通过除以十来连续计算模数和余数。
那么您的复杂度应该是
O(n^2)
,这应该比 15 分钟要好得多。不过,值得一看的是如何除以
10
。编辑
如何一次性将长二进制数除以 10 并获得结果和提醒。没有额外的内存。
简单的伪代码(
a[0]
是最高位数字)让我们举个例子,数字
100111011 = 315
。步骤 0:
r = 1,a[0] = 0
第 1 步:
r = 2,a[1] = 0
第 2 步:
r = 4,a[2] = 0
步骤 3:
r = 9,a[3] = 0
步骤 4:
r = 9,a[4] = 1
第 5 步:
r = 9,a[5] = 1
第 6 步:
r = 8,a[6] = 1
第 7 步:
r = 7,a[7] = 1
步骤 8:
r = 5, a[8] = 1
因此,提醒为
5
,结果为000011111 = 31
。I currently use the maybe (or obviously) somewhat naive way of continuously calculating the modulus and remainder through division through ten.
Then you should have
O(n^2)
complexity, which should fare much better than 15 minutes.Although, it's worth looking how exactly you do division by
10
.edit
How to divide long binary number by 10 in one pass and get both result and reminder. With no additional memory.
Simple pseudo-code (
a[0]
is the highest order digit)Let's take an example, number
100111011 = 315
.Step 0:
r = 1, a[0] = 0
Step 1:
r = 2, a[1] = 0
Step 2:
r = 4, a[2] = 0
Step 3:
r = 9, a[3] = 0
Step 4:
r = 9, a[4] = 1
Step 5:
r = 9, a[5] = 1
Step 6:
r = 8, a[6] = 1
Step 7:
r = 7, a[7] = 1
Step 8:
r = 5, a[8] = 1
So, reminder is
5
and the result is000011111 = 31
.我认为 bc 使用 10^n 作为基数而不是 2。因此每个内部“数字”只是 n 个十进制数字,至少对于十进制输入/输出,问题变得微不足道。
I think that bc is using 10^n as base instead of 2. So every internal "digit" is just n decimal digits and at least for decimal input/output the problem becomes trivial.
无需使用指数:
第一次更新
现在长度不应该成为问题......
There's no need to use exponentiation:
FIRST UPDATE
Now length shouldn't be a problem...