首页
论坛
专栏
课程

[原创]任意长度的二进制字符串和十进制串的转换算法(高精度)

2007-12-4 21:54 12813

[原创]任意长度的二进制字符串和十进制串的转换算法(高精度)

2007-12-4 21:54
12813
因为最近在写一个进制转换器,所以遇到了一些问题,以下是我在写的过程中遇到的已经解决的问题,即如何将一个无限长度的二进制串转换为十进制串的算法。这是群里的一个朋友帮我写的,并非我所写,真的很感谢我的那位朋友,他真的很了不起。
今天我把它共享出来,希望这个程序能对有所需要的朋友提供一些帮助。

#include <stdio.h>
#include <string.h>
#define MAX_LEN 10000

typedef struct{
    int len;
    char value[MAX_LEN];
} TBigInt, *pBigInt;

void AddBit(pBigInt s,char BitValue){    //加一位, 0或者1。 
    int i;
    for (i=0;i<s->len;i++)
        s->value[i]*=2;
    s->value[0]+=BitValue;
    for (i=0;i<s->len;i++){
        s->value[i+1]+=s->value[i]/10;
        s->value[i]%=10;
    }
    if (s->value[s->len]) s->len++;
}

void OutputBigInt(pBigInt s){           //输出大整数类型
    int i;
    if (s->len==0){
        puts("0");
    } else {
        for (i=s->len-1;i>=0;i--)
            putchar(s->value[i]+'0');
        putchar('\n');
    }
}

int main(){
    static char buf[1000000];
    static TBigInt BigInt;
    while (scanf("%s",buf)!=EOF){
        memset(&BigInt,0,sizeof BigInt);
        int i;
        for (i=0;buf[i];i++)
            AddBit(&BigInt,buf[i]=='1'?1:0);
        OutputBigInt(&BigInt);
    }
    return 0;
}


[推荐]看雪企服平台,提供安全分析、定制项目开发、APP等级保护、渗透测试等安全服务!

上一主题 下一主题
最新回复 (9)
combojiang 26 2007-12-5 09:44
2
0
写得不错,收藏。
没有风 10 2007-12-8 12:27
3
0
我写的小程序,实现两个功能。第一个:将任意长度的二进制串转换为十进制串,第二个:将任意长度的十进制串转换为二进制串。由于经验不足,有写得不好的地方请多多原谅。
///////////////////////////////////////////
//transformation.h
////////////////////////////////////////////

#include <string.h>

void Ten2Two(const char* csstrten2two,char* strten2twobin);

void Two2Ten(const char* csstrtwo2ten,char* strtwo2tendec);

/////////////////////////////////////////////////////////////////////////
//transformation.cpp
/////////////////////////////////////////////////////////////////////////

/*
**---------------------------------------------------------------------------------------
**函数原型:void Ten2Two(const char* csstrten2two,char* strten2twobin)
**功能:将一个任意长度的十进制串转换为一个二进制串
**参数:const char* csstrten2two 要转换的十进制串 char* strten2twobin 转换后的二进制串
**返回值:void
**---------------------------------------------------------------------------------------
*/

void Ten2Two(const char* csstrten2two,char* strten2twobin)
{
    int     istdeclen=strlen(csstrten2two);     //存储十进制串的长度
    
    for(int tt=0;tt<istdeclen;tt++){            //如果十进制串为非'0'串(即全部字符为'0')或只有一个字符,提前结束循环
        if(csstrten2two[tt]!='0')break;
    }
    if(tt==istdeclen){                          //如果十进制串为'0'串或只有一个字符,则返回十进制串首字符
        strten2twobin[0]=csstrten2two[0];
        strten2twobin[1]='\0';
        return;
    }

    unsigned int     k=1;                       //存储所有十进制串数码或运算的值,如果为0表示十进制数码串为0串
    unsigned int     quotient=0;                //存储余数
    int     strten2twobinlen=0;                 //二进制串的长度
    int     i,j;                                //循环下标
    char    ctemp;                               //
    char*   strten2two=new char[istdeclen+1];   //分配一临时空间,用来存储十进制串转换的数字码(即'0' '1' '2'等对应的数字0 1 2等)
    
    for(i=0;i<istdeclen;i++){                   //将二进制串转换为数字码并存储到临时空间中去
        strten2two[i]=csstrten2two[i]-'0';
    }
    strten2two[i]='\0';                             

    for(i=0;k;i++){                              //结束条件为被除数为0

        k=0;        //赋0,以便下一次再次十进制串的各位数码的或运算值

        for(j=0;j<istdeclen;j++){               //           

            while(1){                           //把十进制串前面的0过滤掉,不用每次都对十进制串前面的0进行计算
                k+=strten2two[j];              //
                if(k){
                    k=0;
                    break;
                }
                j++;
            }

            quotient=(unsigned)(strten2two[j]%2);       //求数码除以2的余数,关键
            strten2two[j]=(unsigned)strten2two[j]/2;    //求数码除以2的商,关键

            if(j!=istdeclen-1){             //如果j不是指向最后一位,那位将上一位的余数乘以10加进下一个数去
                strten2two[j+1]=(unsigned)(strten2two[j+1]+quotient*10);
            }

            for(int tt=0;tt<istdeclen;tt++){        //求所有数码的和
                k+=strten2two[tt];
            }
        }

        strten2twobin[i]=quotient;                  //除2取余,把所得的余数存储起来,实际上存储的是数字码,关键

        strten2twobinlen++;                         //二进制串的长度加1

    }

    strten2twobin[strten2twobinlen]='\0';          //二进制串未尾加'\0' 
    strten2twobinlen--;                            //二进制串长度减1,使得该指针指向最后一个字符
    
    for(int t=0;t<=strten2twobinlen;t++,strten2twobinlen--){    //将二进制数字码转换为数字字符,并逆序排列
        ctemp=(unsigned)(strten2twobin[t]+'0');
        strten2twobin[t]=(unsigned)(strten2twobin[strten2twobinlen]+'0');
        strten2twobin[strten2twobinlen]=(unsigned)ctemp;
    }


    delete []strten2two;                //释放临时分配的空间
}


/*
**---------------------------------------------------------------------------------------
**函数原型:void Two2Ten(const char* csstrtwo2ten,char* strtwo2tendec)
**功能:将一个任意长度的二进制串转换为一个十进制串
**参数:const char* csstrtwo2ten 要转换的二进制串 char* strtwo2tendec 转换后的十进制串
**返回值:void
**---------------------------------------------------------------------------------------
*/
void Two2Ten(const char* csstrtwo2ten,char* strtwo2tendec)
{
    int     istrtwo2tenlen=strlen(csstrtwo2ten);        //存储二进制串的长度
    int     istrtwo2tendeclen=1;                        //默认十进制串的长度至少为1
    int     i,j;                                        //循环下标

    char    ctemp;                                      //临时变量,逆序排列十进制串时使用
    char*   strtwo2ten=new char[istrtwo2tenlen+1];      //分配一块存储十进制数字码的临时空间
    
    for(i=0;i<istrtwo2tenlen;i++){                      //将十进制串转换为数字码并存储到临时空间
        strtwo2ten[i]=csstrtwo2ten[i]-'0';
    } 

    strtwo2ten[i]='\0';                                 //加上结束标志,好像也可以不加的
    
    //该循环完成将二进制数码转换为十进制数码的工作,每取一位二进制数,对应的十进制数要乘以2并加上所取的二进制数
    for(i=0;i<istrtwo2tenlen;i++){                      //

        for (j=0;j<istrtwo2tendeclen;j++)
            strtwo2tendec[j]*=2;                        //每一位十进制数乘2

        strtwo2tendec[0]+=strtwo2ten[i];                //十进制数个位加上取得的二进制数 
        
        for (j=0;j<istrtwo2tenlen;j++){                 //
            strtwo2tendec[j+1]+=strtwo2tendec[j]/10;      //将每一位的前一位分离出十位,前把它加到该位来
            strtwo2tendec[j]%=10;                         //该位被分离后,保留个位不变
        }        
        if (strtwo2tendec[istrtwo2tendeclen]) istrtwo2tendeclen++;         //如果进来的二进制位使对应十进制数长度增加1
    }


    strtwo2tendec[istrtwo2tendeclen]='\0';                  //

    istrtwo2tendeclen--;                                    //

    for(i=0;i<=istrtwo2tendeclen;i++,istrtwo2tendeclen--){       //完成两个功能,一是将数字码转换为字母,二是将字符串逆序排列
        ctemp=strtwo2tendec[i]+'0';
        strtwo2tendec[i]=strtwo2tendec[istrtwo2tendeclen]+'0';
        strtwo2tendec[istrtwo2tendeclen]=ctemp;
    }

    delete []strtwo2ten;               //释放临时分配的空间
}

////////////////////////////////////////////
//gaojingduten2two.cpp
///////////////////////////////////////////
#include <stdio.h>
#include "
int main(int argc, char* argv[])
{
    char str1[40]="35184304988159";
    char str2[200]="";   
    
    Ten2Two(str1,str2);
    printf("%s\n",str2);

    char str3[100]="111111111111111111100000000000001111111111111";
    char str4[100]="";

    Two2Ten(str3,str4);
    printf("%s\n",str4);
  return 0;
}
//////////////////////////////////////////////////
输出结果:111111111111111111100000000000001111111111111
                35184304988159

北极星2003 25 2007-12-8 18:58
4
0
如果对高精度算法感兴趣可以练习下大整数的+-*/
以及高精度算法过程的中的加速处理
没有风 10 2007-12-8 22:20
5
0
好主意,我试试看。
SmileBoy 2007-12-10 13:50
6
0
速度如何啊?
shinechou 2007-12-12 17:49
7
0
非常感谢并支持您的分享!
shinechou 2007-12-12 17:52
8
0
谢谢您分享代码!不知速度如何?辛苦了!
pengnannan 2007-12-13 16:53
9
0
operate const char * ()const;

请问这是什么函数
gxqcn 2007-12-14 20:47
10
0

可用HugeCalc,它采用了十进制/二进制“双进制内核系统”设计,且内部可高效相互转换,使输入/输出及内部计算均得以高效进行。

例如在 AMD Athlon 64 Processor 3200+ 下,将二进制下的1000000!(18,488,885bits)转成十进制(5,565,709digits)表示仅需7.611619s,效率远超其它工具。

游客
登录 | 注册 方可回帖
返回