补码一位乘法(Booth算法,C语言实现)

补码一位乘法

  • 首先了解下什么是补码?

  补码概念的理解,需要先从“模”的概念开始。 我们可以把模理解为一个容器的容量。当超出这个 容量时,会自动溢出。如:我们最常见到的时钟,其容量 是 12,过了 12 点之后,就会变为 1 点, 2 点……也就是 说,超过12的部分将被丢弃。那么,在这个例子当中,时钟 的模就是12。模的概念可以帮助我们理解补码的含义。

  补码的引出:假设现在时钟的时针指向 4 点的位 置,要使其指向 3 点,可以怎么操作呢?很明显,共有 2 种方法,顺时针拨 11 格(+11),或逆时针拨 1 格(-1)。 (为了区分顺时针和逆时针,我们用正数表示顺时针方 向转动的距离,负数表示逆时针方向转动的距离) 从上面的例子,不难发现,+11 和-1 实现了同样的 作用。主要原因是时钟的模是 12,顺时针旋转代表加法 运算:4+11=15,而达到模的部分会自动溢出,即 15-12= 3,即到达 3 点的位置。逆时针旋转代表减法运算:4-1= 3。在这个例子当中,+11和-1 是完全等价的。也就是说, 负数-1 可以用正数+11 代替,这样就可以把减法运算改 为加法运算。也可以说:+11 就是-1 的补码(模为 12 的 情况下)。

  • 具体的补码一位乘法(Booth算法)

  Booth算法简介

  Booth算法也就是补码1位乘的比较法。被乘数为[X]补,乘数为[Y]补,[P]补为乘积,按执行顺序得出每一步的部分积

  [ P 0] 补 =0, [ P 1] 补 ={[ P 0] 补 +( Yn +1- Yn )[ X ] 补 } 2-1, 
  [ Pn +1] 补 ={[ Pn ] 补 +( Y 1- Y 0)[ X ] 补 }=[ X · Y ] 补 。 Booth算法的运算规则如下。

1)乘数的最低位为 Yn ,在其后再添加一位 Yn +1,其值为0。

2) Yi +1与 Yi 为相邻2位,( Yi +1- Yi )有“ 0”,“ 1”和“-1” 3种情况。
  ① Yi +1- Yi =0( Yi +1 Yi =00或11),部分积直接右移1位。
  ② Yi +1- Yi =1( Yi +1 Yi =10),部分积加[ X ] 补 ,右移1位。
  ③ Yi +1- Yi =-1( Yi +1 Yi =01),部分积加 [- X ] 补 ,右移1位。 3)按以上执行 n +1步,最后一步( i = n +1)不移动。

  • 具体的算法可以看看这个链接https://www.cnblogs.com/xisheng/p/9260861.html
  • 小啊鹏(木木大人)的C语言算法实现
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>

#defineM12

char*Input_X(chara[]);//输入函数X
char*Input_Y(chara[]);//输入函数Y
_BoolBoolInput(chara[]);//判断输入是否合法
char*GetTrue_form(chara[],charcode[]);//由真值求原码
char*GetComplement(chara[],charb[]);//由原码求补码
char*GetComplementOperation(chara[]);//求补运算
char*Booth(chara[],charb[],char[]);//补码一位乘法(Booth算法)
charfor_mean(char a);

intmain()
{
    charflag=‘Y‘;
    while(1)
    {
    charX[M];//X的真值
    charY[M];//Y的真值
    charX_Code[M];//X_原码
    charY_Code[M];//y_原码
    charX_Complement_Code[M];//X_补码
    charY_Complement_Code[M];//Y_补码
    charX_Y_Booth[M];//补码一位乘法的结果

    Input_X(X);
    Input_Y(Y);

    X_Code_P=GetTrue_form(X,X_Code);
    Y_Code_P=GetTrue_form(Y,Y_Code);
    X_Complement_Code_P=GetComplement(X_Code,X_Complement_Code);
    Y_Complement_Code_P=GetComplement(Y_Code,Y_Complement_Code);

    printf("X的原码是:%s\n",GetTrue_form(X,X_Code));
    printf("Y的原码是:%s\n",GetTrue_form(Y,Y_Code));
    printf("X的补码是:%s\n",X_Complement_Code);
    printf("Y的补码是:%s\n",Y_Complement_Code);
    printf("[XY]的真值是:%s\n",Booth(X_Complement_Code,Y_Complement_Code,X_Y_Booth));
    for_mean(flag);
    }
    return0;
}
//循环函数
charfor_mean(chara)
{
    charb;
    while(1){
    printf("是否需要继续运算:(Y/N)");
    setbuf(stdin,NULL);
    scanf("%c",&b);
    setbuf(stdin,NULL);
    a=b;
    if(a==‘Y‘||a==‘y‘)
    {
        printf("输入的是%c\n",a);
        break;
    }
    if(a==‘n‘||a==‘N‘)
    {
        printf("输入的是%c\n",a);
        printf("退出中,再见!");
        exit(0);
    }
    else{
        printf("输入错误!\n");
        continue;
    }
    }
    returna;
}
//输入函数X
char*Input_X(chara[])
{
    fflush(stdin);
    printf("请输入你的二进制真值(被乘数)X=");
    scanf("%s",a);
    while(1)
    {
        if(BoolInput(a))
            break;
        scanf("%s",a);
    }
    printf("你输入的二进制真值X是:%s\n",a);

    returna;
}
//输入函数Y
char*Input_Y(chara[])
{
    fflush(stdin);
    printf("请输入你的二进制真值(乘数)Y=");
    scanf("%s",a);
    while(1)
    {
        if(BoolInput(a))
            break;
        scanf("%s",a);
    }
    printf("你输入的二进制真值Y是:%s\n",a);
    returna;
}

//判断输入是否合法
_BoolBoolInput(chara[])
{
    intcount=0;//小数点出现的次数
    //判断输入位数是否合法
    if(strlen(a)>M-2||strlen(a)<3)
    {
        printf("对不起你输入的长度不对啊!请重新输入:");
        a=NULL;
        returnfalse;
    }
    //判断输入的第一位是否正确!
    if(a[0]!=‘0‘&&a[0]!=‘-‘)
    {
        printf("你输入的第一位就错了啊!请重新输入:");
        a=NULL;
        returnfalse;
    }
    //判断输入为正数后的操作
    if(a[0]==‘0‘)
    {
        if(a[1]!=‘.‘)
        {
        printf("零后面应该是小数点啊,兄弟!!请重新输入:");
        returnfalse;
        }
    }
    //判断输入为负数后的操作
    if(a[0]==‘-‘)
    {
        if(a[1]!=‘0‘||a[2]!=‘.‘)
        {
        printf("负号后面应该接的零啊,老哥!!请重新输入:");
        returnfalse;
        }
    }
    //判断是否有除0,1,-以外的字符输入
    for(inti=1;i<strlen(a);i++)
    {
        if(a[i]!=‘0‘&&a[i]!=‘1‘&&a[i]!=‘.‘)
        {
            printf("老哥你输入的不是二进制的真值啊!请重新输入:");
            a=NULL;
            returnfalse;
        }
        if(a[i]==‘.‘)
        {
            count++;
        }
    }
    //判断输入的小数点个数是否合法
    if(count>1)
    {
        printf("老哥你输入的小数点有%d个,这多了啊!请重新输入",count);
        a=NULL;
        returnfalse;
    }
    returntrue;
}

//由真值求原码
char*GetTrue_form(chara[],charcode[])
{
    intflag=0;
    //如果真值是负数符号为置为1
    if(a[0]==‘-‘)
    {
        code[0]=‘1‘;
        if(a[1]==‘0‘)
        {
            for(inti=1;i<strlen(a);i++)
            {
                if(a[i]==‘1‘)
                    flag=1;
                code[i]=a[i+1];
                if(flag==0)
                    code[strlen(a)]=‘0‘;
            }
            code[strlen(a)+1]=‘\0‘;
            returncode;
        }
        //
        else
        {
            for(inti=1;i<strlen(a);i++)
            {
                code[i]=a[i];
            }
            code[strlen(a)+1]=‘\0‘;
        }
        returncode;
    }
    //反之置为0
    else
    {
        for(inti=0;i<strlen(a);i++)
        {
            code[i]=a[i];

        }
        code[strlen(a)]=‘\0‘;
    }
    returncode;
}
//原码转化补码
char*GetComplement(chara[],charb[])
{
    for(inti=0;i<strlen(a);i++)
    {
        b[i]=a[i];
    }
    b[strlen(a)+1]=‘\0‘;
    //正数的补码就是原码
    if(b[0]==‘0‘)
    {
        returnb;
    }
    //负数的补码转化
    if(b[0]==‘1‘)
    {
        intj=0;//定位低位往高位遇到的第一个‘1‘.
        for(inti=strlen(b);i>1;i--)
        {
            if(b[i]==‘1‘)
            {
                j=i;
                break;
            }
        }
        //具体的原码转补码,低位往高位遇到的第一个‘1‘往前的取反,符号位不变!
        for(inti=1;i<j;i++)
        {
            if(b[i]==‘1‘)
            {
                b[i]=‘0‘;
                continue;
            }
            if(b[i]==‘0‘)
            {
                b[i]=‘1‘;
                continue;
            }
        }

    }
    returnb;
}

//求补运算,将一个数(包括正数和负数)所有二进制位(包括符号位和数值位)取反,然后在最低位加上1。
char*GetComplementOperation(chara[])
{
    //取反
    for(inti=0;i<strlen(a);i++)
    {
        if(a[i]==‘1‘)
        {
            a[i]=‘0‘;
            continue;
        }
        elseif(a[i]==‘0‘)
        {
            a[i]=‘1‘;
        }
    }
    //加1操作
    //判断最后一位是不是0如果是0则只在最后一位加1
    if(a[strlen(a)-1]==‘0‘)
    {
        a[strlen(a)-1]=‘1‘;
        returna;
    }
    for(inti=strlen(a);i>0;i--)
    {
        if(a[i]==‘1‘)
        {
            a[i]==‘0‘;
            continue;
        }
        if(a[i]==‘0‘)
        {
            a[i]==‘1‘;
            break;
        }
    }
    returna;
}

//补码一位乘法(Booth算法)
char*Booth(chara[],charb[],chard[])
{
    charc=‘0‘;//进位
    charb_Temp;//一位过程中需要的临时变量
    charX_ComplementOperation[M];//[-X]补
    chara_Temp[M];
    //首先统一位数
    intX_i;//x补码的长度
    intY_i;//y补码的长度
    intLength_Difference=0;//长度的差值
    X_i=strlen(a);
    Y_i=strlen(b);
    printf("x的位数%d和y的位数是:%d\n",X_i,Y_i);
    printf("X的补码为:%s\n",a);
    printf("Y的补码为:%s\n",b);
    if(X_i>Y_i)
    {
        printf("我比Y的位数大\n");
        Length_Difference=X_i-Y_i;
        for(inti=0;i<Length_Difference;i++)
        {
            b[Y_i+i]=‘0‘;
        }
        b[Y_i+Length_Difference]=‘\0‘;
    }
    if(X_i<Y_i)
    {
        printf("我比Y的位数小\n");
        Length_Difference=Y_i-X_i;
        for(inti=0;i<Length_Difference;i++)
        {
            a[X_i+i]=‘0‘;
        }
        a[Y_i+Length_Difference+1]=‘\0‘;
    }
    printf("\n");
    printf("统一符号位X的补码变为:%s\n",a);
    printf("统一符号位Y的补码变为:%s\n",b);
    printf("\n");
    //把X的补码变为双符号位的
    intX_Length=0;//X的长度
    intY_Length=0;//Y的长度
    X_Length=strlen(a);
    Y_Length=strlen(b);

    chartemp;
    temp=a[0];
    for(inti=strlen(a)-1;i>0;i--)
    {
        a[i+1]=a[i];
        if(a[i]==‘.‘)
            break;
    }
    a[0]=temp;
    a[1]=temp;
    a[X_Length+1]=‘\0‘;

    printf("将X的补码变为双符号位:%s\n",a);
    stpcpy(a_Temp,a);
    //求[-X]补
    GetComplementOperation(a_Temp);
    for(inti=0;i<strlen(a_Temp);i++)
    {
        X_ComplementOperation[i]=a_Temp[i];
    }
    X_ComplementOperation[strlen(a_Temp)]=‘\0‘;
    printf("X求补是:%s\n",X_ComplementOperation);

    //对Y的最后一位补0操作

    b[Y_Length]=‘0‘;
    b[Y_Length+1]=‘\0‘;

    printf("对Y的补码最低位加0后:%s\n",b);

    //具体的运算过程
    X_Length=strlen(a);
    Y_Length=strlen(b);
    charCn;//高位
    charCn_1;//地位
    charRegister[X_Length+Y_Length];//寄存器数组

    //初始化寄存器数组
    for(inti=0;i<X_Length;i++)
    {
        if(a[i]==‘.‘)
        {
            Register[i]=‘.‘;
            continue;
        }
        Register[i]=‘0‘;
    }
    for(inti=0;i<Y_Length;i++)
    {
        Register[i+X_Length]=b[i];
    }
    Register[X_Length+Y_Length]=‘\0‘;

    printf("寄存器初始的数据:%s",Register);

    //除去小数点Register
    for(inti=0;i<strlen(Register);i++)
    {
        if(Register[i]==‘.‘)
        {
            for(intj=i;j<strlen(Register);j++)
            {
                Register[j]=Register[j+1];
            }
        }
    }
    printf("寄存器初始的数据:%s\n",Register);
    //除去小数点X_ComplementOperation
    for(inti=0;i<strlen(X_ComplementOperation);i++)
    {
        if(X_ComplementOperation[i]==‘.‘)
        {
            for(intj=i;j<strlen(X_ComplementOperation);j++)
            {
                X_ComplementOperation[j]=X_ComplementOperation[j+1];
            }
        }
    }
    //除去小数点a
    for(inti=0;i<strlen(a);i++)
    {
        if(a[i]==‘.‘)
        {
            for(intj=i;j<strlen(a);j++)
            {
                a[j]=a[j+1];
            }
        }
    }
    //开始进行比较
    charflag=‘D‘;
    for(inti=0;i<Y_Length-2;i++)
    {
        Cn=Register[strlen(Register)-2];
        Cn_1=Register[strlen(Register)-1];
        if(Cn==‘0‘&&Cn_1==‘0‘)
            flag=‘A‘;
        if(Cn==‘1‘&&Cn_1==‘1‘)
            flag=‘A‘;
        if(Cn==‘0‘&&Cn_1==‘1‘)
            flag=‘B‘;
        if(Cn==‘1‘&&Cn_1==‘0‘)
            flag=‘C‘;
        printf("操作数的高位是:%c低位是:%c\n",Cn,Cn_1);
        switch(flag)
        {
            //操作1:右移一位
            case‘A‘:
            {
                if(i<Y_Length-3)
                {
                    for(intj=strlen(Register)-1;j>1;j--)
                    {
                        Register[j]=Register[j-1];
                    }
                    Register[1]=Register[0];
                }
                printf("移位操作后寄存器的数据:%s\n",Register);
                break;
            }

            //操作2:加上X的补,并右移一位
            case‘B‘:
            {
                //加的操作
                //printf("a的值是:%s\n",a);

                for(intj=strlen(a)-1;j>=0;j--)
                {
                    //设置尾是否有进位数
                    if(j==strlen(a)-1)
                    {
                        if(Register[j]==‘1‘&&a[j]==‘1‘)
                        {
                            c=‘1‘;
                            Register[j]=‘0‘;
                            continue;
                        }
                        if(Register[j]==‘1‘&&a[j]==‘0‘)
                        {
                            c=‘0‘;
                            Register[j]=‘1‘;
                            continue;
                        }
                        if(Register[j]==‘0‘&&a[j]==‘1‘)
                        {
                            c=‘0‘;
                            Register[j]=‘1‘;
                            continue;
                        }
                    }
                    if(Register[j]==‘1‘)
                    {
                        if(a[j]==‘0‘&&c==‘0‘)
                        {
                            continue;
                        }
                        elseif(a[j]==‘0‘&&c==‘1‘)
                        {
                            Register[j]=‘0‘;
                            c=‘1‘;
                            continue;
                        }
                        elseif(a[j]==‘1‘&&c==‘0‘)
                        {
                            Register[j]=‘0‘;
                            c=‘1‘;
                            continue;
                        }
                        elseif(a[j]==‘1‘&&c==‘1‘)
                        {
                            Register[j]=‘1‘;
                            c=‘1‘;
                            continue;
                        }
                    }
                    if(Register[j]==‘0‘)
                    {
                        if(a[j]==‘0‘&&c==‘0‘)
                        {
                            continue;
                        }
                        elseif(a[j]==‘0‘&&c==‘1‘)
                        {
                            Register[j]=‘1‘;
                            c=‘0‘;
                            continue;
                        }
                        elseif(a[j]==‘1‘&&c==‘0‘)
                        {
                            Register[j]=‘1‘;
                            c=‘0‘;
                            continue;
                        }
                        elseif(a[j]==‘1‘&&c==‘1‘)
                        {
                            Register[j]=‘0‘;
                            c=‘1‘;
                            continue;
                        }
                    }
                }

                //printf("未移位寄存器的数据:%s\n",Register);
                //移位的操作
                if(i<Y_Length-3)
                {
                    for(intj=strlen(Register)-1;j>1;j--)
                    {
                        Register[j]=Register[j-1];
                    }
                    Register[1]=Register[0];
                }
                printf("B操作后寄存器的数据:%s\n",Register);
                break;
            }

            //操作3:加上-X的补,并右移一位
            case‘C‘:
            {
                //加-x补码的操作
                //printf("X_ComplementOperation的值是:%s",X_ComplementOperation);
                for(intj=strlen(X_ComplementOperation)-1;j>=0;j--)
                {
                    //设置尾是否有进位数
                    if(j==strlen(a)-1)
                    {
                        if(Register[j]==‘1‘&&a[j]==‘1‘)
                        {
                            c=‘1‘;
                            Register[j]=‘0‘;
                            continue;
                        }
                        if(Register[j]==‘1‘&&a[j]==‘0‘)
                        {
                            c=‘0‘;
                            Register[j]=‘1‘;
                            continue;
                        }
                        if(Register[j]==‘0‘&&a[j]==‘1‘)
                        {
                            c=‘0‘;
                            Register[j]=‘1‘;
                            continue;
                        }
                    }

                    //加
                    if(Register[j]==‘1‘)
                    {
                        if(X_ComplementOperation[j]==‘0‘&&c==‘0‘)
                        {
                            continue;
                        }
                        elseif(X_ComplementOperation[j]==‘0‘&&c==‘1‘)
                        {
                            Register[j]=‘0‘;
                            c=‘1‘;
                            continue;
                        }
                        elseif(X_ComplementOperation[j]==‘1‘&&c==‘0‘)
                        {
                            Register[j]=‘0‘;
                            c=‘1‘;
                            continue;
                        }
                        elseif(X_ComplementOperation[j]==‘1‘&&c==‘1‘)
                        {
                            Register[j]=‘1‘;
                            c=‘1‘;
                            continue;
                        }
                    }
                    if(Register[j]==‘0‘)
                    {
                        if(X_ComplementOperation[j]==‘0‘&&c==‘0‘)
                        {
                            continue;
                        }
                        elseif(X_ComplementOperation[j]==‘0‘&&c==‘1‘)
                        {
                            Register[j]=‘1‘;
                            c=‘0‘;
                            continue;
                        }
                        elseif(X_ComplementOperation[j]==‘1‘&&c==‘0‘)
                        {
                            Register[j]=‘1‘;
                            c=‘0‘;
                            continue;
                        }
                        elseif(a[j]==‘1‘&&c==‘1‘)
                        {
                            Register[j]=‘0‘;
                            c=‘1‘;
                            continue;
                        }
                    }
                }

                //printf("未移位是寄存器的数据:%s\n",Register);
                //移位的操作
                if(i<Y_Length-3)
                {
                    for(intj=strlen(Register)-1;j>1;j--)
                    {
                        Register[j]=Register[j-1];
                    }
                    Register[1]=Register[0];
                }
                printf("C操作后寄存器的数据:%s\n",Register);
                break;
            }
            default:
            {
                printf("对不起,出现无法解决的错误,程序将要退出!\n");
                exit(0);
            }
        }
    }
    printf("最后寄存器的数据:%s\n",Register);
    //转化为补码
    for(inti=0;i<strlen(Register)-2;i++)
    {
        d[i]=Register[i];
    }
    d[strlen(Register)-2]=‘\0‘;
    if(d[0]==‘0‘)
    {
        d[1]=‘.‘;
    }
    if(d[0]==‘1‘)
    {
        d[1]=‘.‘;
        d[strlen(Register)]=‘\0‘;
    }
    printf("[X*Y]补是:%s\n",d);
    //转化为真值
    if(d[0]==‘1‘)
    {
        d[0]=‘-‘;
        d[1]=‘0‘;
        for(inti=strlen(d);i>2;i--)
        {
            d[i]=d[i-1];
        }
        d[2]=‘.‘;
        d[strlen(Register)]=‘\0‘;
    }
    returnd;
}

我也知道大家可能主要是需要算法的具体实现,因此代码中注解较多。

这里我也欢迎大家交流,希望大家可以指出代码里的错误和不足,谢谢!

参考文献

[1]武涛,智洋,白丽珍.三种机器码的联系与剖析[J].大学教育,2017(04):18-19+22.

[2]王晓东,富坤,耿恒山,秘海晓,孙晓丽.在8位微程序控制的模型计算机中Booth算法的实现[J].河北科技大学学报,2012,33(05):443-447.

下面说下我的运行环境(在window VS中可能无法运行):

操作系统:Ubuntu16

编译器:gcc

原文地址:https://www.cnblogs.com/mumu597/p/11827058.html

时间: 2024-10-28 20:25:11

补码一位乘法(Booth算法,C语言实现)的相关文章

[计算机组成原理] Booth算法 —— 补码一位乘法

x * y = z 运算规则: 1.和原码一位乘法不同,补码一位乘法的符号位是参加运算的,且运算结果和所有参加运算的数都是补码形式. 2.乘数 x 取双符号位参与运算,部分积的初始值为0: 乘数 y 取单符号位参与运算. 3.乘数 y 首先在末尾添加一个辅助位 0 ,每次讨论都是取 y 的最后两位,但每次移动仅移动一位. 4.判断 y 的最后两位是规则如下: 00 或者 11 时,直接右移一位: 01 时,先加 x 的补,然后右移一位: 10 时,先加 -x 的补,然后右移一位. 5.有个特例,

大整数算法[13] 单数位乘法

★ 引子 最近在折腾 wxWidgets,同时拖延症又犯了,所以中断了好久.这次来讲讲单数位乘法,前面讲到 Comba 和 Karatsuba 乘法,这两个算法适合用来处理比较大的整数,但是对于一个大整数和一个单精度数相乘,其效果反而会不好,因为计算量过多.实际上单数位乘法只是基线乘法的一个特例,不存在嵌套循环进位,因此可以通过优化减少计算量.另外与完整的乘法不同的是,单数位乘法不需要什么临时变量存储和内存分配(目标精度增加除外). ★ 算法思路         单数位乘法类似于计算 12345

BOOTH 算法的简单理解

学习FPGA时,对于乘法的运算,尤其是对于有符号的乘法运算,也许最熟悉不过的就是 BOOTH算法了. 这里讲解一下BOOTH算法的计算过程,方便大家对BOOTH的理解.        上图是BOOTH算法的数学表达.由于FPGA擅长进行并行移位计算,所以BOOTH算法倒也好实现. 上图是对乘数的加码过程,具体可以见下面的例子. 7 x (-3),其中R1表示被乘数 7, R2 表示乘数 -3,那么二者对应的补码,为 R1 0111,R2 1101, P代码最终结果容量,应该为 2x 4 + 1

布斯乘法Booth&#39;s multiplication algorithm from wikipedia

Booth's multiplication algorithm is a multiplication algorithm that multiplies two signed binary numbers in two's complement notation. The algorithm was invented by Andrew Donald Booth in 1950 while doing research on crystallography at Birkbeck Colle

booth算法实现乘法器

booth算法充分的利用到了补码的重要性,使得我们在利用补码进行计算时减少了很多时序.下面的表格是我们假设2 作为乘数所进行的分析.接下来,我将用代码向大家阐述. 1.开始的时候在乘数2的‘负一位’加上一个默认0值 00100  2.先判断[0:-1],结果是2‘b00,表示’0‘ 即没有操作 00100  3.判断[1:0] 结果是2’b10,表示‘1’即‘-被乘数’操作 00100             4.判断[2:1]结果是2‘b10,表示’1‘即’+被乘数‘操作 00100  5.判

SHA-1算法c语言实现

安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准 (Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA).对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要.当接收到消息的时候,这个消息摘要可以用来验证数据的完整性.在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要. SHA1有如下特性:不可以从消息摘要中复原信息:两个不同的消息不

多项式乘法快速算法

多项式乘法优化算法: 设有如下两个多项式: 把它们的系数分别做成向量X=[x0,x1,x2,x3,......]的形式,得 F=[2,3,1] G=[5,2,0] 那么根据卷积公式 可以求得向量F和G的卷积S=[10,19,11,2] 而由多项式乘法可算出 各项系数和上面的卷积结果正好一一对应. 所以说,多项式相乘,相当于系数向量的卷积. 再仔细观察一下这个多项式:每个系数正好对应的就是频域 Reference: http://www.cnblogs.com/bigcat/archive/200

PID算法(C语言)

/************ PID算法(C语言) ************/ #include <stdio.h> #include<math.h> struct _pid { int pv; /*integer that contains the process value*/ int sp; /*integer that contains the set point*/ float integral; float pgain; float igain; float dgain;

快速排序算法-C语言实现

注:本篇内容为翻译,之所以选择这篇进行翻译原因是该文章含有动画,能够更加直观地展示快速排序.同时,可以仔细看一下代码,代码中把结构化的思想给予了更加充分地表现.按照功能进行模块划分的思想得到了彻底地贯彻. 以下内容翻译自: http://cprogramminglanguage.net/quicksort-algorithm-c-source-code.aspx 译文: 在快速排序算法中,使用了分治策略.首先把序列分成两个子序列,递归地对子序列进行排序,直到整个序列排序结束. 步骤如下: 在序列