[英]binary to decimal base shift
我需要一种算法,可以将任意大小的无符号整数(以二进制格式存储)转换为十进制数。 即使其易于阅读;)
我目前使用(也许很显然)有些天真的方法来连续计算模数和除以十的余数。
不幸的是,速度有些... la脚。
例如,我计算了2000 ^ 4000(使用我的bignum库),这大约需要1.5秒(请不要燃烧,请xD)。 但是,包括必要的基本转换的打印大约需要15分钟,这很烦人。
我已经测试了bc,而这两个过程都不到一秒钟。
它是如何做到的? (不是与ffts相乘的东西,仅与基本转换无关)
我目前使用(也许很显然)有些天真的方法来连续计算模数和除以十的余数。
然后,您应该具有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
。
我认为bc使用10 ^ n而不是2作为基数。因此,每个内部“数字”仅是n个十进制数字,至少对于十进制输入/输出,问题变得微不足道了。
无需使用幂运算:
#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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.