征集c语言的多字节的加减乘除?
c语言的:
我们经常会遇到多字节的加、减、乘、除,现在请各位大虾讨论一下,多字节的算法问题?
for example:
1. a[]={0x20,0x21,0x22,0x23}
b[]={0x10,0x11,0x12,0x13}
求a+b;
a-b;
a*b;
a/b;
[解决办法]
大数运算
[解决办法]
见意找计算机组成原理的书看,里面有关于二进制加、减、乘、除的运算过程。
[解决办法]
大数运算的思想就是用数组保存某个数字的各个数据位,
然后进行运算,并同样分割保存结果。
参考下面:
/*用数组存储数字,可以超越数据类型的限制,实现极大数的加法,减法和乘法 */
/*2005-3-7 梁见斌*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 80
int a[MAX]={0}, b[MAX]={0};
int *r, *s;
char e[40], f[40];/* e[30]和f[30]存放以字符串形式输入的乘数和被乘数*/
char *p, *q;
void NiZhi(int *ShuZu, int len);/*把数字逆置,把个位数字存储在a[0]*/
void ZhuanHuan(char *ZhiFu, int *ShuZi, int len);/*把字符改存为整型数字*/
int PanDuan(int len);/*当len1=len2时判断a[]和 b[]谁大 */
void JiaFa(int len1, int len2);
void JianFa(int len1, int len2);
void ChengFa(int len1, int len2);
int main(void)
{
int len1, len2;
int choice;
do{
puts( "请您选择操作的方式: ");
puts( "\t加法请按1 ");
puts( "\t减法请按2 ");
puts( "\t乘法请按3 ");
scanf( "%d ", &choice);
}while(choice < 1 || choice > 3);
r=a;
s=b;
p=e;
q=f;
puts( "Inter m: ");
scanf( "%s ", p);
puts( "Inter n: ");
scanf( "%s ", q);
len1=strlen(e);
len2=strlen(f);
ZhuanHuan(p, r, len1);
ZhuanHuan(q, s, len2);
NiZhi(r, len1);
NiZhi(s, len2);
switch(choice)
{
case 1: JiaFa(len1, len2);
break;
case 2: JianFa(len1, len2);
break;
case 3: ChengFa(len1, len2);
break;
default: printf( "It 's error ");
}
system( "pause ");
return 0;
}
void NiZhi(int *ShuZu, int len)
{
int i, t;
for(i=0; i <len/2; i++)
{
t=*(ShuZu+i);
*(ShuZu+i)=*(ShuZu+len-i-1);
*(ShuZu+len-i-1)=t;
}
}
void ZhuanHuan(char *ZhiFu, int *ShuZi, int len)
{
int i;
for(i=0; i <=len-1; i++)
*(ShuZi+i)=int(*(ZhiFu+i))-48;
}
void ChengFa(int len1, int len2)
{
int i, j, k;
int c[MAX]={0}, aa[MAX]={0};/*a[max]和aa[max]存放被乘数,b[max]存放乘数,c[max]存放积*/
int x, jinwei, d;
for(i=0; i <=len2; i++)
{
for(j=0; j <=len1; j++)/*每次都使 aa[ ]表示被乘数*/
aa[j]=a[j];
d=20;/*提供足够多的存储空间以存放积的进位,此处设为20,可根据数据的大小调节*/
jinwei=0;/*c表示积的进位,初值为0*/
for(j=0; j <=len1+d; j++)/*用乘数的每一位从个位开始依次和被乘数相乘,用aa[ ]存储当前积*/
{
x=aa[j]*b[i]+jinwei;
jinwei=x/10;
aa[j]=x%10;
}
while(a[j] == 0)/*用j表示现有数字的个数,多出的存储空间应消除*/
j--;
d=4;/*提供足够多的存储空间以存放积的进位,此处设为4,可根据数据的大小调节*/
jinwei=0;/*c表示积的进位,初值为0*/
for(k=0; k <=j+d; k++)/*c[max]存放原始积,注意每次把当前积与原始积时相加时两者的位置对应情况*/
{
x=aa[k]+c[k+i]+jinwei;
jinwei=x/10;
c[k+i]=x%10;
}
}
k=k+i; /*用k表示现有数字的个数,多出的存储空间应消除*/
while(c[k] == 0)
k--;
printf( "%s * %s =\n ", p, q);
for(i=k; i> =0; i--)
printf( "%d ",c[i]);
}
void JiaFa(int len1, int len2)
{
int i, j;
int x, jinwei, max;
max=(len1 > = len2)?len1:len2;
jinwei=0;
for(i=0; i <=max+2; i++)
{
x=a[i]+b[i]+jinwei;
jinwei=x/10;
a[i]=x%10;
}
while(a[i] == 0)/*用j表示现有数字的个数,多出的存储空间应消除*/
i--;
printf( "%s + %s =\n ", p, q);
for(j=i; j> =0; j--)
printf( "%d ",a[j]);
}
void JianFa(int len1, int len2)
{
int i, j;
int max;
int flag=0;
if(len1 == len2)/*当len1=len2时判断a[]和 b[]谁大 */
flag=PanDuan(len1);
if((len1 > len2) || (len1 == len2) && flag)/*若m大于n直接按m-n计算*/
{
for(i=0; i <len1; i++)
{
if(a[i] > = b[i])
a[i]=a[i]-b[i];
else
{
a[i+1]-=1;
a[i]=a[i]+10-b[i];
}
}
while(a[i] == 0)/*用j表示现有数字的个数,多出的存储空间应消除*/
i--;
printf( "%s - %s =\n ", p, q);
for(j=i; j> =0; j--)
printf( "%d ",a[j]);
}
else/*若m小于n,则按n-m计算,输出结果前面加负号*/
{
for(i=0; i <len2; i++)
{
if(b[i] > = a[i])
b[i]=b[i]-a[i];
else
{
b[i+1]-=1;
b[i]=b[i]+10-a[i];
}
}
while(b[i] == 0)/*用j表示现有数字的个数,多出的存储空间应消除*/
i--;
printf( "%s - %s =\n ", p, q);
printf( "- ");
for(j=i; j> =0; j--)
printf( "%d ",b[j]);
}
}
int PanDuan( int len)
{
int i=len;
while(a[i] > = b[i] && i > = 0)
i--;
if(i > = 0)
return 0;
else if((i < 0) && (a[i+1] == b[i+1]))
{
printf( "\nThe answer is 0 ");
system( "pause ");
exit(0);
}
else
return 1;
}
[解决办法]
如果要求比较高的话,瞌睡虫贴的代码实在是太低效了。以前练习的时候也做过类似的,但真正用起来还是会下载专业的库。
比较好的办法不是对通用的数组写一组函数,而是直接封装一个大整数数据类型。
像这样(具体实现就不写了,当时写得实在是不怎么样):
/******************************************************************************
integer.h
大整数类型
类型定义与函数声明
作者:milksea
最后编辑:2006年12月31日
******************************************************************************/
#ifndef INTEGER_H
#define INTEGER_H
enum {
Ninit= 1,/* 按Base[P]进制存储的初始位数,Base定义见integer.c */
P= 2
};
typedef struct {
unsigned long *digit;/* 按Base[P]进制存储的数位 */
intsizedigit;/* 按Base[P]进制,当前分配的位数 */
intndigit;/* 数字按Base[P]进制的实际位数 */
intsign;/* 符号:0、1、-1 */
} Integer_st, *Integer;
extern const Integer Zero_int;
extern const Integer One_int;
extern const Integer MinusOne_int;
/******************************* 函数声明 ************************************/
/* create:构造类函数 */
Integer createZero_int(void);/* 大整数0 */
Integer createCStr_int(char *s);/* 用C风格字符串构造大整数 */
Integer createStr_int(PSeqString s);/* 用字符串构造大整数 */
Integer createCInt_int(int i);/* 用内置的int类型来构造大整数 */
Integer createInt_int(Integer x);/* 复制构造函数 */
void destroy_int(Integer x);/* 析构函数 */
/* 输入输出与类型转化函数 */
Bool fprint_int(FILE *ofp, Integer x);
Bool print_int(Integer x);
Bool fscan_int(FILE *ifp, Integer x);
Bool scan_int(Integer x);
/* assign类函数:设x为某值,并返回x,错误返回NULL */
Integer assignCStr_int(Integer x, char *s);/* 用C风格字符串设值 */
Integer assignStr_int(Integer x, PSeqString s);/* 用字符串设值 */
Integer assignCInt_int(Integer x, int i);/* 用int设值 */
Integer assignInt_int(Integer x, const Integer y);/* x = y */
/* 运算类函数:将运算结果保存于result,并返回result,错误返回NULL。
内容包括相反数、绝对值、加法、减法、除法、乘幂、阶乘。 */
Integer opposite_int(const Integer x, Integer result);
Integer abs_int(const Integer x, Integer result);
Integer plus_int(const Integer x, const Integer y, Integer result);
Integer minus_int(const Integer x, const Integer y, Integer result);
Integer mult_int(const Integer x, const Integer y, Integer result);
Integer powerCInt_int(const Integer x, int n, Integer result);
Integer power_int(const Integer x, const Integer n, Integer result);
Integer factorial_int(const Integer x, Integer result);
/* 运算赋值类函数:将运算结果赋于第一个运算分量x,并返回x,错误返回NULL。
一元运算赋值将改变自身。内容同运算类函数。如assignplus就是“+=”运算。 */
Integer increase_int(Integer x);/* ++x */
Integer decrease_int(Integer x);/* --x */
Integer assignopposite_int(Integer x);
Integer assignabs_int(Integer x);
Integer assignplus_int(Integer x, const Integer y);
Integer assignminus_int(Integer x, const Integer y);
Integer assignmult_int(Integer x, const Integer y);
Integer assignpowerCInt_int(Integer x, int n);
Integer assignpower_int(Integer x, const Integer n);
Integer assignfactorial_int(Integer x);
/* 比较函数:x > y返回1,x < y返回-1,x == y返回0。
还包括绝对值大小比较 */
int cmp_int(const Integer x, const Integer y);
int abscmp_int(const Integer x, const Integer y);
int sign_int(const Integer x);/* 符号,即与0比较 */
/* 其他函数 */
int getdig_int(const Integer x, int n);/* 十进制右数第n位,错误返回-1 */
int getndig_int(const Integer x);/* 十进制位数 */
#endif/* INTEGER_H */