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的超长的除法 TKS 坛子里以前有过汇编版本的计算 这么做太奢侈了,还是用汇编更实用。不过作为算法分析的c语言题目倒还是有点用 收藏了,谢谢楼主分享! 对于有硬件乘除法器的MCU下,这个应该用处不大。 好东西,现在用不上,留着以后用 在某些场合,还是很有用的。 高精度嘛 收藏了! 大数运算是大学的一个课程设计哦~ mark ,做一个标记 好东西 ,收藏了???谢谢楼主 先看看。。。。。 记号!!! 学习了,支持一下. 学习一下吧,如此运算对8位单片机太奢侈了,还是汇编靠谱的多 目前有些MCU都内嵌MDU了,不过这个算法也可以学习一下,在不带MDU的MCU中也挺好的 挺不错的算法 收藏了,谢谢楼主分享! 学习一下,正好可以用上! 收藏,日后也许能用上,谢谢楼主分享! 一般的大数运算,编译器应该可以直接处理吧。 收藏了,谢谢! 这个其实还是有点用处,不过很小众了 好东西,飘过!! 超過32bits可用! 收藏了! cool, 学习中 这个不错 mark 大数运算,收藏了
不错,mark备用 大数运算,精华啊 不错,以后肯定有用得着的地方,作个记号
不错,以后肯定有用得着的地方,作个记号
不错,作个记号{:handshake:} Mark,收藏啦! 好东西,收藏 收藏先 标记学习, 大数运算
收藏先{:smile:} 这个不错,以前得自己写 标记一下, 好东西 学习了 http://item.jd.com/10828943.html 这本书里面有说过的 我当年想做一个计算器这没做成! 学习了。记下 感觉就是加法和减法,这个编译器自带32或64位的处理库,按照32位的最大值21亿来说,需要处理多久呢 很好很强大,感谢LZ分享。{:handshake:} 最近正好需要。。。感谢楼主。。。{:lol:} 这个挺不错!!!! 可以参考参考 mark... 收藏了,谢谢! mark,。。。。 对于有硬件乘除法器的MCU下,这个应该用处不大 mark {:smile:}标记一下,下次要用到再看,谢谢楼主分享 可以有!! 谢谢分享! 这个有用,留记号 这个确实啊,要是mcu带有硬件乘法器之类的,那上面的也就没有什么用了。 做密码算法挺有用处的~ 记号一下。还是很有用的。 谢谢楼主分享! 以前看到过!现在再仔细学习下!! 这个算是个算法吧 BUGbug不管你们说怎么样,我认为对于我等菜鸟还是必须要收藏的!顶! 非常感谢啊,今天面试,要求用8位单片机实现乘法运算。我不会做,现在学习了,谢谢啊!{:smile:} 收藏了,谢谢楼主分享! 虽然现在用不到。还是MARK一下,备用吧。谢谢楼主了! 大数运算,学习了~
不错,以后肯定有用得着的地方,作个记号
谢谢分享。。。。。。。。。。。。。。。 这个 很不错 mark。。。。。 不错!!!!!!! 还记得,刚刚毕业去面试的时候做的题目就是类似的! 学习一下~~~~~ 汇编的都有了 这个还是有点复杂的 学习一下,,,, 这么厉害 上述代码 line129-133是错的,算出来的余数不正确!
可参考下述代码(肯定不唯一)
k = 0;
while(szByNum == 0);
for(j=k-1;j<=nByNumLen-1;j++)
{
szByNum+='0';
}
*remainder = &szByNum;
我真是闲的蛋疼,人工跑代码,卡壳了。。。 果断收藏,算法很重要 收藏备用 谢谢分享................ 又知道了还有这么样的一种东西。。。。长见识了。。。。 谢谢楼主分享! 很厉害呀,不错 正需要,感谢楼主!
页:
[1]