我需要一种算法,将任意大小的无符号整数(以二进制格式存储)转换为十进制整数。即使其具有人类可读性;)
我目前使用通过十分的连续计算模数和余数的可能(或显然)有点天真的方式
不幸的是,速度有点......蹩脚。
e.g。 我计算2000 ^ 4000(使用我的bignum库)需要大约1.5秒(没有火焰请xD)。然而,包括必要的碱基转换的印刷品大约需要15分钟,这非常烦人。
我测试了bc,它在不到一秒的时间内完成了两次 它是如何做到的? (不是ffts的乘法和任何基础转换)
答案 0 :(得分:2)
我目前使用可能(或显然)有点天真的方式通过十分来连续计算模数和余数。
然后你应该有O(n^2)
复杂度,这应该比15分钟更好。
虽然,值得看看你是如何按10
划分的。
修改强>
如何在一遍中将长二进制数除以10得到结果和提醒。没有额外的记忆。
简单的伪代码(a[0]
是最高位数)
int r = 0;
for (int i = 0; i < n; ++i) {
r = r * 2 + a[i];
a[i] = r / 10;
r = r % 10;
}
我们举个例子,编号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
。
答案 1 :(得分:1)
我认为bc使用10 ^ n作为基数而不是2.所以每个内部“数字”只是n个十进制数字,至少对于十进制输入/输出,问题变得微不足道。
答案 2 :(得分:0)
无需使用取幂:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int main(){
char a[] = "10011";
unsigned long int res= 0;
int i;
for(i = 0; i < strlen(a); i++){
res = (res<<1) + (a[i]-'0');
}
printf("%d",res);
return 0;
}
第一次更新
现在长度应该不是问题...
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
char *doubles(char *);
char *sum(char *,int);
int main(){
char a[] = "10011";
char *res = calloc(2,sizeof(char));
int i;
res[0] = '0';
for(i = 0; i < strlen(a); i++){
res = sum(doubles(res),(a[i]-'0'));
}
printf("%s",res);
return 0;
}
char *doubles(char *s){
int i,len = strlen(s),t = 0;
char *d;
d = calloc(len+1,sizeof(char));
for(i = 0; i < len; i++){
t = ((s[len-i-1]-'0')<<1) + t;
d[len-i] = ('0' + (t%10));
t = t/10;
}
d[0] = t+'0';
return (d[0] == '0')?d+1:d;
}
char *sum(char *s,int n){
int i, len = strlen(s),t = n;
char *d = calloc(len+1,sizeof(char));
for(i = 0; i < len ; i++){
t = (s[len-i-1]-'0') + t;
d[len-i] = ('0' + (t%10));
t = t/10;
}
d[0] = t+'0';
return (d[0] == '0')?d+1:d;
}