搜索
bottom↓
回复: 90

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

  [复制链接]

出0入0汤圆

发表于 2012-5-15 10:39:31 | 显示全部楼层 |阅读模式
  1. #include <REGX52.H>
  2. #include "stdio.h"
  3. #include "string.h"                 
  4. #include "intrins.h"

  5. #define BIT 10
  6. //WriteBy :Rlogin Xukaiming
  7. /************************************************************************
  8. 函数功能: 大数计算
  9.    参数1: char szByNum[] //被乘数  
  10.    参数2: char szNum[]   //乘数   
  11.    参数3: char aryResult[]   //积 用来放结果              
  12. ************************************************************************/
  13. void BigNumMul(char szByNum[], char szNum[], char aryResult[])
  14. {
  15.     int nByNumLen, nNumLen, nTempLen, nResultLen ;
  16.     int i,j,k,l;
  17.         //结果长度
  18.         nByNumLen         =   strlen(szByNum);
  19.         nNumLen                =   strlen(szNum);       
  20.         nResultLen  =         nNumLen+ nByNumLen;  
  21.     //乘数长度从右向左依次
  22.         l =  nResultLen-1;
  23.     for (i = nNumLen-1; i >= 0; i--)
  24.     {
  25.             
  26.         nTempLen = l;
  27.                
  28.         for (j = nByNumLen-1; j >= 0; j--, nTempLen--)
  29.         {
  30.             //结果第一次从最后一位开始,第二次从倒数第二位开始放                                                                                          
  31.                         aryResult[nTempLen] = aryResult[nTempLen] + (szNum[i] - '0') * (szByNum[j] -'0');
  32.         }
  33.         
  34.         //进位处理
  35.         for (k = l; k >0; k--)                           //从后往前处理
  36.         {
  37.             if (aryResult[k] > BIT)
  38.             {
  39.                 aryResult[k-1] = aryResult[k-1] + aryResult[k] / BIT;
  40.                 aryResult[k] = aryResult[k] % BIT;
  41.             }
  42.         }
  43.                 //下一次得从倒数第二位开始
  44.         l--;
  45.     }
  46.                                                                                          
  47.         for(nResultLen=nResultLen-1;nResultLen>=0;nResultLen--)                //变成字符串
  48.         {
  49.                 aryResult[nResultLen]+='0';
  50.                 _nop_();
  51.         }
  52.        
  53.         _nop_();
  54. }

  55. /************************************************************************
  56. 函数功能: 大数计算
  57.    参数1: char szByNum[] //被除数  
  58.    参数2: char szNum[]   //乘数   
  59.    参数3: char aryResult[]   //商 用来放结果  
  60.    参数4: char remainder[]   //余数 用来放结果             
  61. ************************************************************************/
  62. void BigNumDiv(char szByNum[], char szNum[], char quotient[],char **remainder )
  63. {
  64.         int nByNumLen, nNumLen, nTempLen, nResultLen ;       
  65.         int j,k,l=0;
  66.         nByNumLen         =   strlen(szByNum);
  67.         nNumLen                =   strlen(szNum);       
  68.         nResultLen  =         nByNumLen - nNumLen+1;   //估计商数的长度

  69.          //将除数和被除数变成10进制数字
  70.         for(j=nByNumLen-1;j>=0;j--)
  71.         {
  72.                 szByNum[j] -='0';
  73.         }
  74.         for(j=nNumLen-1;j>=0;j--)
  75.         {
  76.                    szNum[j] -= '0';
  77.         }
  78.         ///////////////////////////////除法就是减法 ?
  79.        
  80.         for(j=nResultLen-1;j>=0;j--)
  81.         {       
  82.                 quotient[l]=0;   
  83.                 while(1)
  84.                 {
  85.                         quotient[l]++;                                  //商数加1
  86.                         for(k=nNumLen-1;k>=0;k--)         //减除数的长度即可         
  87.                         {                                                                
  88.                                 szByNum[k+l]-=szNum[k];          //减掉除数
  89.                                 if(szByNum[k+l]<0)
  90.                                 {                                                                     
  91.                                         //if((l!=0)||(k+l>1))                //第一次防止借位借到-1位
  92.                                         if(k+l>0)
  93.                                         {                                  
  94.                                                 szByNum[k+l-1]-=1;           //借位=10                
  95.                                                 szByNum[k+l]+=BIT;                                                
  96.                                         }
  97.                                          
  98.                                 }
  99.                                
  100.                         }        //(szByNum[0]<0)||(
  101.                         if(((l==0)&&(szByNum[l]<0))                                 //符号判断,看有负数没?
  102.                         ||((l>0)&&(szByNum[l-1]<0)))
  103.                         {       
  104.                                 quotient[l]--;
  105.                                 for(k=nNumLen-1;k>=0;k--)
  106.                                 {
  107.                                         szByNum[k+l]+=szNum[k];                   //变成了负数,要加回来
  108.                                         if(szByNum[k+l]>=BIT)
  109.                                         {
  110.                                                 if(k+l>0)                          //第一次防止借位借到-1位
  111.                                                 {
  112.                                                         szByNum[k+l-1]+=1;
  113.                                                         szByNum[k+l]-=BIT;       
  114.                                                 }         
  115.                                                                                                   
  116.                                         }
  117.                                 }
  118.                                 _nop_();
  119.                                 break;                                         
  120.                         }        
  121.                 }         
  122.                 quotient[l]+='0';   //转为ASCII
  123.                 l++;
  124.                
  125.         }
  126.         for(j=l;j<nByNumLen-1;j++)
  127.         {
  128.                 szByNum[j]+='0';
  129.         }
  130.         *remainder = &szByNum[l];
  131.         quotient[l] = '\0';
  132. }


  133. xdata char strByNum[8], strNum[8];          
  134. xdata char arrayResult[50] = {0};

  135. xdata char arrayquotient[8];
  136. xdata char *arrayremainder;

  137. int main()
  138. {

  139.     int i;

  140.         TH1 = 0xFE;
  141.         TR1 = 1;
  142.     TI = 1;

  143.     //printf("请输入被乘数: ");
  144.         strcpy(strByNum,"9000");                         
  145.     printf("\n被除数: ");
  146.         printf(strByNum);
  147.         strcpy(strNum,"299");
  148.         printf("\n除数: ");
  149.         printf(strNum);               
  150.         //strcpy(arrayquotient,"123");
  151.         memset(arrayResult,0,sizeof(arrayResult));            
  152.     //BigNumMul(strByNum, strNum, arrayResult);         
  153.            BigNumDiv(strByNum, strNum, arrayquotient,&arrayremainder);         
  154.     printf("\n商数: ");
  155.     printf(arrayquotient);
  156.         printf("\n余数: ");
  157.         printf(arrayremainder);
  158.     printf("\r\n");       
  159.         while(1);          
  160.     return 0;
  161. }
复制代码
输入输出均为10进制 字符串

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

出0入0汤圆

发表于 2012-5-15 10:52:11 | 显示全部楼层
TKS               

出0入4汤圆

发表于 2012-5-15 11:01:58 | 显示全部楼层
坛子里以前有过汇编版本的计算

出0入0汤圆

发表于 2012-5-15 12:14:33 | 显示全部楼层
这么做太奢侈了,还是用汇编更实用。不过作为算法分析的c语言题目倒还是有点用

出0入0汤圆

发表于 2012-5-15 12:20:45 | 显示全部楼层
收藏了,谢谢楼主分享!

出0入0汤圆

发表于 2012-5-15 13:05:13 | 显示全部楼层
对于有硬件乘除法器的MCU下,这个应该用处不大。

出0入0汤圆

发表于 2012-5-15 14:37:28 | 显示全部楼层
好东西,现在用不上,留着以后用

出50入0汤圆

发表于 2012-5-15 16:03:37 | 显示全部楼层
在某些场合,还是很有用的。

出0入0汤圆

发表于 2012-5-15 16:33:02 来自手机 | 显示全部楼层
高精度嘛

出0入0汤圆

发表于 2012-5-15 18:16:45 | 显示全部楼层
收藏了!

出0入0汤圆

发表于 2012-11-15 07:26:29 来自手机 | 显示全部楼层
大数运算是大学的一个课程设计哦~

出0入0汤圆

发表于 2012-11-16 16:54:04 | 显示全部楼层
mark ,做一个标记

出0入0汤圆

发表于 2012-11-18 22:01:02 | 显示全部楼层
好东西 ,收藏了???谢谢楼主

出0入0汤圆

发表于 2012-11-18 22:04:42 | 显示全部楼层
先看看。。。。。

出0入0汤圆

发表于 2012-11-18 22:05:04 | 显示全部楼层
记号!!!

出0入0汤圆

发表于 2012-11-19 15:39:39 | 显示全部楼层
学习了,支持一下.

出0入0汤圆

发表于 2012-11-21 21:54:53 | 显示全部楼层
学习一下吧,如此运算对8位单片机太奢侈了,还是汇编靠谱的多

出0入0汤圆

发表于 2012-11-26 16:00:24 | 显示全部楼层
目前有些MCU都内嵌MDU了,不过这个算法也可以学习一下,在不带MDU的MCU中也挺好的

出0入0汤圆

发表于 2012-11-26 16:10:19 | 显示全部楼层
挺不错的算法

出0入0汤圆

发表于 2012-12-10 21:51:07 | 显示全部楼层
收藏了,谢谢楼主分享!

出0入0汤圆

发表于 2012-12-22 13:16:50 | 显示全部楼层
学习一下,正好可以用上!

出0入0汤圆

发表于 2012-12-25 18:56:51 | 显示全部楼层
收藏,日后也许能用上,谢谢楼主分享!

出0入0汤圆

发表于 2012-12-25 22:05:06 | 显示全部楼层
一般的大数运算,编译器应该可以直接处理吧。

出0入0汤圆

发表于 2013-1-8 08:52:13 | 显示全部楼层
收藏了,谢谢!

出0入0汤圆

发表于 2013-1-8 11:57:48 | 显示全部楼层
这个其实还是有点用处,不过很小众了

出0入0汤圆

发表于 2013-1-8 14:52:30 | 显示全部楼层
好东西,飘过!!

出0入0汤圆

发表于 2013-1-8 16:47:50 | 显示全部楼层
超過32bits可用!

出0入0汤圆

发表于 2013-1-8 17:00:56 | 显示全部楼层
收藏了!

出0入0汤圆

发表于 2013-1-18 11:26:26 | 显示全部楼层
cool, 学习中

出0入0汤圆

发表于 2013-1-29 13:18:50 | 显示全部楼层
这个不错 mark

出0入0汤圆

发表于 2013-2-4 08:46:20 | 显示全部楼层
大数运算,收藏了

出0入0汤圆

发表于 2013-2-4 12:32:50 | 显示全部楼层
不错,mark备用

出0入0汤圆

发表于 2013-2-17 11:37:04 | 显示全部楼层
大数运算,精华啊

出0入0汤圆

发表于 2013-2-17 13:08:38 | 显示全部楼层
不错,以后肯定有用得着的地方,作个记号

出0入0汤圆

发表于 2013-3-29 16:50:49 | 显示全部楼层

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

出0入0汤圆

发表于 2013-4-25 00:59:06 | 显示全部楼层
不错,作个记号

出0入0汤圆

发表于 2013-5-31 21:59:37 | 显示全部楼层
Mark,收藏啦!

出0入0汤圆

发表于 2013-6-3 17:18:50 | 显示全部楼层
好东西,收藏

出0入0汤圆

发表于 2013-7-29 10:50:10 | 显示全部楼层
收藏先               

出0入0汤圆

发表于 2013-9-2 10:02:33 | 显示全部楼层
标记学习, 大数运算

出0入0汤圆

发表于 2013-10-31 07:39:57 | 显示全部楼层
收藏先  

出0入0汤圆

发表于 2013-10-31 08:18:09 来自手机 | 显示全部楼层
这个不错,以前得自己写

出0入0汤圆

发表于 2013-10-31 08:37:49 | 显示全部楼层
标记一下,

出0入0汤圆

发表于 2014-3-22 08:28:20 | 显示全部楼层
好东西 学习了

出0入0汤圆

发表于 2014-3-22 08:54:40 | 显示全部楼层
http://item.jd.com/10828943.html   这本书里面有说过的

出0入0汤圆

发表于 2014-3-22 09:09:01 | 显示全部楼层
我当年想做一个计算器这  没做成!

出0入0汤圆

发表于 2014-3-22 09:11:00 | 显示全部楼层
学习了。记下

出0入0汤圆

发表于 2014-3-22 10:10:18 | 显示全部楼层
感觉就是加法和减法,这个编译器自带32或64位的处理库,按照32位的最大值21亿来说,需要处理多久呢

出0入0汤圆

发表于 2014-3-22 11:45:08 | 显示全部楼层
很好很强大,感谢LZ分享。

出0入0汤圆

发表于 2014-3-22 13:23:09 | 显示全部楼层
最近正好需要。。。感谢楼主。。。

出0入0汤圆

发表于 2014-3-22 13:47:20 | 显示全部楼层
这个挺不错!!!!

出0入0汤圆

发表于 2014-3-22 14:20:29 | 显示全部楼层
可以参考参考

出0入0汤圆

发表于 2014-3-22 14:36:25 | 显示全部楼层
mark...   

出0入8汤圆

发表于 2014-4-3 11:01:26 | 显示全部楼层
收藏了,谢谢!

出0入0汤圆

发表于 2014-4-24 12:35:05 | 显示全部楼层
mark,。。。。

出0入0汤圆

发表于 2014-4-24 15:24:06 | 显示全部楼层
对于有硬件乘除法器的MCU下,这个应该用处不大

出0入0汤圆

发表于 2014-4-24 16:35:53 | 显示全部楼层
mark      

出0入0汤圆

发表于 2014-4-24 18:28:55 | 显示全部楼层
标记一下,下次要用到再看,谢谢楼主分享

出0入4汤圆

发表于 2014-5-23 22:08:19 | 显示全部楼层
可以有!!

出0入0汤圆

发表于 2014-5-24 08:10:57 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2014-5-24 08:26:45 | 显示全部楼层
这个有用,留记号

出0入0汤圆

发表于 2014-5-24 08:50:19 | 显示全部楼层
这个确实啊,要是mcu带有硬件乘法器之类的,那上面的也就没有什么用了。

出0入4汤圆

发表于 2014-5-24 09:11:10 | 显示全部楼层
做密码算法挺有用处的~

出0入0汤圆

发表于 2014-6-10 00:19:56 来自手机 | 显示全部楼层
记号一下。还是很有用的。

出0入0汤圆

发表于 2014-6-10 08:20:45 | 显示全部楼层
谢谢楼主分享!

出0入0汤圆

发表于 2014-6-10 17:09:13 | 显示全部楼层
以前看到过!现在再仔细学习下!!

出0入0汤圆

发表于 2014-6-18 17:15:05 | 显示全部楼层
这个算是个算法吧

出0入0汤圆

发表于 2014-6-18 17:26:35 | 显示全部楼层
BUGbug不管你们说怎么样,我认为对于我等菜鸟还是必须要收藏的!顶!

出0入0汤圆

发表于 2014-7-7 17:22:56 | 显示全部楼层
非常感谢啊,今天面试,要求用8位单片机实现乘法运算。我不会做,现在学习了,谢谢啊!

出0入0汤圆

发表于 2014-7-7 17:49:58 | 显示全部楼层
收藏了,谢谢楼主分享!

出0入0汤圆

发表于 2014-7-7 21:17:20 | 显示全部楼层
虽然现在用不到。还是MARK一下,备用吧。谢谢楼主了!

出0入0汤圆

发表于 2014-7-8 17:11:15 | 显示全部楼层
大数运算,学习了~

出0入0汤圆

发表于 2014-7-8 22:57:03 | 显示全部楼层

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

出0入0汤圆

发表于 2014-7-8 22:58:42 | 显示全部楼层
谢谢分享。。。。。。。。。。。。。。。

出0入0汤圆

发表于 2014-7-8 23:17:24 | 显示全部楼层
这个 很不错

出0入0汤圆

发表于 2014-7-9 10:09:45 | 显示全部楼层
mark。。。。。

出0入0汤圆

发表于 2014-8-29 10:50:56 | 显示全部楼层
不错!!!!!!!

出0入0汤圆

发表于 2014-8-29 11:09:49 | 显示全部楼层
还记得,刚刚毕业去面试的时候做的题目就是类似的!

出0入0汤圆

发表于 2014-9-10 16:08:28 | 显示全部楼层
学习一下~~~~~

出0入0汤圆

发表于 2014-9-10 16:33:08 | 显示全部楼层
汇编的都有了

出0入0汤圆

发表于 2014-9-10 16:42:43 | 显示全部楼层
这个还是有点复杂的

出0入4汤圆

发表于 2014-9-10 17:48:26 来自手机 | 显示全部楼层
学习一下,,,,

出0入0汤圆

发表于 2014-9-10 18:17:24 | 显示全部楼层
这么厉害

出0入0汤圆

发表于 2014-9-10 21:34:12 | 显示全部楼层
上述代码 line129-133是错的,算出来的余数不正确!
可参考下述代码(肯定不唯一)
    k = 0;
    while(szByNum[k++] == 0);
    for(j=k-1;j<=nByNumLen-1;j++)
    {
        szByNum[j]+='0';
    }
    *remainder = &szByNum[k-1];
我真是闲的蛋疼,人工跑代码,卡壳了。。。

出0入16汤圆

发表于 2014-9-11 13:05:08 | 显示全部楼层
果断收藏,算法很重要

出0入0汤圆

发表于 2014-10-10 10:45:54 | 显示全部楼层
收藏备用

出0入0汤圆

发表于 2014-10-20 14:18:57 | 显示全部楼层
谢谢分享................

出0入0汤圆

发表于 2014-10-20 14:28:26 | 显示全部楼层
又知道了还有这么样的一种东西。。。。长见识了。。。。

出0入0汤圆

发表于 2014-10-20 15:44:28 | 显示全部楼层
谢谢楼主分享!

出0入0汤圆

发表于 2014-10-20 16:57:49 | 显示全部楼层
很厉害呀,不错

出0入0汤圆

发表于 2015-1-16 10:14:59 来自手机 | 显示全部楼层
正需要,感谢楼主!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号 )

GMT+8, 2022-6-26 00:40

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表