rlogin 发表于 2012-5-15 10:39:31

8位单片机,大数运算,可以运算任意位数的乘除法

#include <REGX52.H>
#include "stdio.h"
#include "string.h"               
#include "intrins.h"

#define BIT 10
//WriteBy :Rlogin Xukaiming
/************************************************************************
函数功能: 大数计算
   参数1: char szByNum[] //被乘数
   参数2: char szNum[]   //乘数   
   参数3: char aryResult[]   //积 用来放结果          
************************************************************************/
void BigNumMul(char szByNum[], char szNum[], char aryResult[])
{
    int nByNumLen, nNumLen, nTempLen, nResultLen ;
    int i,j,k,l;
        //结果长度
        nByNumLen         =   strlen(szByNum);
        nNumLen                =   strlen(szNum);       
        nResultLen=         nNumLen+ nByNumLen;
    //乘数长度从右向左依次
        l =nResultLen-1;
    for (i = nNumLen-1; i >= 0; i--)
    {
          
      nTempLen = l;
               
      for (j = nByNumLen-1; j >= 0; j--, nTempLen--)
      {
            //结果第一次从最后一位开始,第二次从倒数第二位开始放                                                                                          
                        aryResult = aryResult + (szNum - '0') * (szByNum -'0');
      }
      
      //进位处理
      for (k = l; k >0; k--)                           //从后往前处理
      {
            if (aryResult > BIT)
            {
                aryResult = aryResult + aryResult / BIT;
                aryResult = aryResult % BIT;
            }
      }
                //下一次得从倒数第二位开始
      l--;
    }
                                                                                       
        for(nResultLen=nResultLen-1;nResultLen>=0;nResultLen--)                //变成字符串
        {
                aryResult+='0';
                _nop_();
        }
       
        _nop_();
}

/************************************************************************
函数功能: 大数计算
   参数1: char szByNum[] //被除数
   参数2: char szNum[]   //乘数   
   参数3: char aryResult[]   //商 用来放结果
   参数4: char remainder[]   //余数 用来放结果           
************************************************************************/
void BigNumDiv(char szByNum[], char szNum[], char quotient[],char **remainder )
{
        int nByNumLen, nNumLen, nTempLen, nResultLen ;       
        int j,k,l=0;
        nByNumLen         =   strlen(szByNum);
        nNumLen                =   strlen(szNum);       
        nResultLen=         nByNumLen - nNumLen+1;   //估计商数的长度

       //将除数和被除数变成10进制数字
        for(j=nByNumLen-1;j>=0;j--)
        {
                szByNum -='0';
        }
        for(j=nNumLen-1;j>=0;j--)
        {
                   szNum -= '0';
        }
        ///////////////////////////////除法就是减法 ?
       
        for(j=nResultLen-1;j>=0;j--)
        {       
                quotient=0;   
                while(1)
                {
                        quotient++;                                //商数加1
                        for(k=nNumLen-1;k>=0;k--)       //减除数的长度即可       
                        {                                                              
                                szByNum-=szNum;          //减掉除数
                                if(szByNum<0)
                                {                                                                 
                                        //if((l!=0)||(k+l>1))                //第一次防止借位借到-1位
                                        if(k+l>0)
                                        {                                  
                                                szByNum-=1;           //借位=10              
                                                szByNum+=BIT;                                                
                                        }
                                       
                                }
                               
                        }        //(szByNum<0)||(
                        if(((l==0)&&(szByNum<0))                               //符号判断,看有负数没?
                        ||((l>0)&&(szByNum<0)))
                        {       
                                quotient--;
                                for(k=nNumLen-1;k>=0;k--)
                                {
                                        szByNum+=szNum;                 //变成了负数,要加回来
                                        if(szByNum>=BIT)
                                        {
                                                if(k+l>0)                          //第一次防止借位借到-1位
                                                {
                                                        szByNum+=1;
                                                        szByNum-=BIT;       
                                                }       
                                                                                                  
                                        }
                                }
                                _nop_();
                                break;                                       
                        }        
                }       
                quotient+='0';   //转为ASCII
                l++;
               
        }
        for(j=l;j<nByNumLen-1;j++)
        {
                szByNum+='0';
        }
        *remainder = &szByNum;
        quotient = '\0';
}


xdata char strByNum, strNum;          
xdata char arrayResult = {0};

xdata char arrayquotient;
xdata char *arrayremainder;

int main()
{

    int i;

        TH1 = 0xFE;
        TR1 = 1;
    TI = 1;

    //printf("请输入被乘数: ");
        strcpy(strByNum,"9000");                       
    printf("\n被除数: ");
        printf(strByNum);
        strcpy(strNum,"299");
        printf("\n除数: ");
        printf(strNum);               
        //strcpy(arrayquotient,"123");
        memset(arrayResult,0,sizeof(arrayResult));          
    //BigNumMul(strByNum, strNum, arrayResult);       
           BigNumDiv(strByNum, strNum, arrayquotient,&arrayremainder);       
    printf("\n商数: ");
    printf(arrayquotient);
        printf("\n余数: ");
        printf(arrayremainder);
    printf("\r\n");       
        while(1);          
    return 0;
}
输入输出均为10进制 字符串

应用范围 ,加密解密,DDS的超长的除法

flotox 发表于 2012-5-15 10:52:11

TKS               

wajlh 发表于 2012-5-15 11:01:58

坛子里以前有过汇编版本的计算

learner123 发表于 2012-5-15 12:14:33

这么做太奢侈了,还是用汇编更实用。不过作为算法分析的c语言题目倒还是有点用

shiningjohn 发表于 2012-5-15 12:20:45

收藏了,谢谢楼主分享!

tiancaigao7 发表于 2012-5-15 13:05:13

对于有硬件乘除法器的MCU下,这个应该用处不大。

w1000 发表于 2012-5-15 14:37:28

好东西,现在用不上,留着以后用

yuzr 发表于 2012-5-15 16:03:37

在某些场合,还是很有用的。

aheadlead 发表于 2012-5-15 16:33:02

高精度嘛

shunda 发表于 2012-5-15 18:16:45

收藏了!

ShawnLinson 发表于 2012-11-15 07:26:29

大数运算是大学的一个课程设计哦~

sweet_136 发表于 2012-11-16 16:54:04

mark ,做一个标记

853728579 发表于 2012-11-18 22:01:02

好东西 ,收藏了???谢谢楼主

dujuan8693 发表于 2012-11-18 22:04:42

先看看。。。。。

pcwinner 发表于 2012-11-18 22:05:04

记号!!!

lryxr2507 发表于 2012-11-19 15:39:39

学习了,支持一下.

leesnow 发表于 2012-11-21 21:54:53

学习一下吧,如此运算对8位单片机太奢侈了,还是汇编靠谱的多

lechoate 发表于 2012-11-26 16:00:24

目前有些MCU都内嵌MDU了,不过这个算法也可以学习一下,在不带MDU的MCU中也挺好的

chkchk 发表于 2012-11-26 16:10:19

挺不错的算法

beyond870215 发表于 2012-12-10 21:51:07

收藏了,谢谢楼主分享!

yanming 发表于 2012-12-22 13:16:50

学习一下,正好可以用上!

freeboyxd 发表于 2012-12-25 18:56:51

收藏,日后也许能用上,谢谢楼主分享!

LCRPN 发表于 2012-12-25 22:05:06

一般的大数运算,编译器应该可以直接处理吧。

ouyu 发表于 2013-1-8 08:52:13

收藏了,谢谢!

bbssilverkey 发表于 2013-1-8 11:57:48

这个其实还是有点用处,不过很小众了

guowanling8061 发表于 2013-1-8 14:52:30

好东西,飘过!!

jlian168 发表于 2013-1-8 16:47:50

超過32bits可用!

beyond870215 发表于 2013-1-8 17:00:56

收藏了!

wuqiushan741826 发表于 2013-1-18 11:26:26

cool, 学习中

LGDSTM 发表于 2013-1-29 13:18:50

这个不错 mark

liupeng08305 发表于 2013-2-4 08:46:20

大数运算,收藏了

Coobila 发表于 2013-2-4 12:32:50

不错,mark备用

yuguoliang 发表于 2013-2-17 11:37:04

大数运算,精华啊

four_zhg 发表于 2013-2-17 13:08:38

不错,以后肯定有用得着的地方,作个记号

pxq8410 发表于 2013-3-29 16:50:49


不错,以后肯定有用得着的地方,作个记号

asong14437546 发表于 2013-4-25 00:59:06

不错,作个记号{:handshake:}

Elec_Ramble 发表于 2013-5-31 21:59:37

Mark,收藏啦!

zzz123456 发表于 2013-6-3 17:18:50

好东西,收藏

kevinchen026 发表于 2013-7-29 10:50:10

收藏先               

bondxie3 发表于 2013-9-2 10:02:33

标记学习, 大数运算

sfq2008 发表于 2013-10-31 07:39:57

收藏先{:smile:}

divineliu 发表于 2013-10-31 08:18:09

这个不错,以前得自己写

hhucwyd 发表于 2013-10-31 08:37:49

标记一下,

greenflyqqq 发表于 2014-3-22 08:28:20

好东西 学习了

rossih 发表于 2014-3-22 08:54:40

http://item.jd.com/10828943.html   这本书里面有说过的

磊磊映画 发表于 2014-3-22 09:09:01

我当年想做一个计算器这没做成!

KK_K 发表于 2014-3-22 09:11:00

学习了。记下

mcu5i51 发表于 2014-3-22 10:10:18

感觉就是加法和减法,这个编译器自带32或64位的处理库,按照32位的最大值21亿来说,需要处理多久呢

lkm_unication 发表于 2014-3-22 11:45:08

很好很强大,感谢LZ分享。{:handshake:}

永恒520 发表于 2014-3-22 13:23:09

最近正好需要。。。感谢楼主。。。{:lol:}

iop 发表于 2014-3-22 13:47:20

这个挺不错!!!!

wiser803 发表于 2014-3-22 14:20:29

可以参考参考

caizhihe11 发表于 2014-3-22 14:36:25

mark...   

jianjun42 发表于 2014-4-3 11:01:26

收藏了,谢谢!

yanglei920509 发表于 2014-4-24 12:35:05

mark,。。。。

jiwx2011 发表于 2014-4-24 15:24:06

对于有硬件乘除法器的MCU下,这个应该用处不大

michael.yang 发表于 2014-4-24 16:35:53

mark      

liupeng08305 发表于 2014-4-24 18:28:55

{:smile:}标记一下,下次要用到再看,谢谢楼主分享

sunliezhi 发表于 2014-5-23 22:08:19

可以有!!

ZYBing 发表于 2014-5-24 08:10:57

谢谢分享!

gmajvfhpa 发表于 2014-5-24 08:26:45

这个有用,留记号

wallemm 发表于 2014-5-24 08:50:19

这个确实啊,要是mcu带有硬件乘法器之类的,那上面的也就没有什么用了。

蓝蓝的恋 发表于 2014-5-24 09:11:10

做密码算法挺有用处的~

15813191501 发表于 2014-6-10 00:19:56

记号一下。还是很有用的。

ZYBing 发表于 2014-6-10 08:20:45

谢谢楼主分享!

夜里的雪 发表于 2014-6-10 17:09:13

以前看到过!现在再仔细学习下!!

edkaifa 发表于 2014-6-18 17:15:05

这个算是个算法吧

jiang887786 发表于 2014-6-18 17:26:35

BUGbug不管你们说怎么样,我认为对于我等菜鸟还是必须要收藏的!顶!

hxszk 发表于 2014-7-7 17:22:56

非常感谢啊,今天面试,要求用8位单片机实现乘法运算。我不会做,现在学习了,谢谢啊!{:smile:}

ltmooner 发表于 2014-7-7 17:49:58

收藏了,谢谢楼主分享!

kgje 发表于 2014-7-7 21:17:20

虽然现在用不到。还是MARK一下,备用吧。谢谢楼主了!

奮闘ing 发表于 2014-7-8 17:11:15

大数运算,学习了~

seekor2012 发表于 2014-7-8 22:57:03


不错,以后肯定有用得着的地方,作个记号

seekor2012 发表于 2014-7-8 22:58:42

谢谢分享。。。。。。。。。。。。。。。

1066950103 发表于 2014-7-8 23:17:24

这个 很不错

机器人天空 发表于 2014-7-9 10:09:45

mark。。。。。

mybadthing 发表于 2014-8-29 10:50:56

不错!!!!!!!

hht594 发表于 2014-8-29 11:09:49

还记得,刚刚毕业去面试的时候做的题目就是类似的!

cqsgcqsg 发表于 2014-9-10 16:08:28

学习一下~~~~~

limuzi2012 发表于 2014-9-10 16:33:08

汇编的都有了

foxcase 发表于 2014-9-10 16:42:43

这个还是有点复杂的

chen_ym 发表于 2014-9-10 17:48:26

学习一下,,,,

tongli 发表于 2014-9-10 18:17:24

这么厉害

didadida 发表于 2014-9-10 21:34:12

上述代码 line129-133是错的,算出来的余数不正确!
可参考下述代码(肯定不唯一)
    k = 0;
    while(szByNum == 0);
    for(j=k-1;j<=nByNumLen-1;j++)
    {
      szByNum+='0';
    }
    *remainder = &szByNum;
我真是闲的蛋疼,人工跑代码,卡壳了。。。

TigerFish 发表于 2014-9-11 13:05:08

果断收藏,算法很重要

pch888 发表于 2014-10-10 10:45:54

收藏备用

qxc16b 发表于 2014-10-20 14:18:57

谢谢分享................

panhai0101 发表于 2014-10-20 14:28:26

又知道了还有这么样的一种东西。。。。长见识了。。。。

xueyulangren 发表于 2014-10-20 15:44:28

谢谢楼主分享!

shiqianjudan 发表于 2014-10-20 16:57:49

很厉害呀,不错

hubinghuandi 发表于 2015-1-16 10:14:59

正需要,感谢楼主!
页: [1]
查看完整版本: 8位单片机,大数运算,可以运算任意位数的乘除法