首页 > 栏目列表 > 正文

高精度加法

高精度加法
阅读数27180
高精度加法
冷月寒笙
冷月寒笙
个性签名:生活就像海洋,只有强者才能到达彼岸。不畏艰难,勇往直前,成就卓越人生。

pascal高精度减法

  1、和高精度加法相比,减法在差为负数时处理的细节更多一点:当被减数小于减数时,差为负数,差的绝对值是减数减去被减数;在程序实现上用一个变量来存储符号位,用另一个数组存差的绝对值。

  2、算法流程:

  (1)读入被减数S1,S2(字符串);

  (2)置符号位:判断被减数是否大于减数:大则将符号位置为空;小则将符号位置为“-”,交换减数与被减数;

  (3)被减数与减数处理成数值,放在数组中;

  (4)运算:

  A、取数;

  B、判断是否需要借位;

  C、减,将运算结果放到差数组相应位中;

  D、判断是否运算完成:是,转5;不是,转A;

  (5)打印结果:符号位,第1位,循环处理第2到最后一位;

  3、细节:

  ▲如何判断被减数与减数的大小:字符串知识

  ①(1)首先将两个字符串的位数补成一样(因为字符串的比较是从左边对齐的;两个字符串一样长才能真正地比较出大小):短的在左边补0

  k1:=length(s1);

  k2:=length(s2);

  if k1>k2 then for i:=1 to k1-k2 do s2:='0'+s2

  else for i:=1 to k2-k1 do s1:='0'+s1;

  (2)接着比较大小:直接比较字符串大小

  fh:='';

  if s1<s2 then begin fh:='-';s:=s1; s1:=s2; s2:=s; end;

  {————s1存被减数,符号存符号}

  ②通过数组分析完成大小比较(当数值长度超过256位时发挥重要作用)

  readln(s);{输入整个算式,即'a+b='}

  l1:=pos('-',s);(搜索'-'的位置)

  for i:=1 to l1-1 do {从字符串中分离出数值A}

  a[l1-i]:=ord(s[i])-48;

  dec(l1);{将'-'号位置转换为数值A的长度}

  x2:=length(s);{获取算式长度}

  l2:=x2-l1-2;{得到数值B长度}

  for i:=l1+2 to x2 do{将数值B分离出}

  b[x2-i]:=ord(s[i])-48;

  if l2>l1 then p:=true{开始分析数值AB的大小,如果B位数高则B更大}

  else if l2=l1 then{如果相等则进入详细分析}

  begin

  i:=l1;

  while (i>0)and(a[i]=b[i]) do dec(i);{从高到低依次检索AB每位的大小,如果有非等于则退出}

  if a[i]<b[i] then p:=true;{最终判断数值AB的大小}

  end;

  ▲将字符串处理成数值:

  l:=length(s1);{求出s1的长度,也即s1的位数;有关字符串的知识。}

  k1:=260;

  for i:=l downto 1 do

  begin

  a[k1]:=ord(s1)-48;{将字符转成数值}

  k1:=k1-1;

  end;

  k1:=k1+1;

  ▲打印结果:

  例:差:第一位是12,第二位是234,第三位是1234,最后一位:3。它的实际数值是12023412340003。

  从上例可以看出:打印时,从第二位开始,因为每一段都代表4位,不足4位的要补足0。

  write(fh,c[k]);{k是差的第1位;}

  for i:=k+1 to 260 do

  begin

  if c<1000 then write('0');

  if c<100 then write('0');

  if c<10 then write('0');

  write(c);

  end;

  程序源代码:

  {PASCAL}

  Program a1;

  var a,b,c:array [1..100] of integer;

  x2,l1,l2,i:integer;

  p:boolean;

  s:string;

  begin

  readln(s);

  l1:=pos('-',s);

  for i:=1 to l1-1 do

  a[l1-i]:=ord(s[i])-48;

  dec(l1);

  x2:=length(s);

  l2:=x2-l1-2;

  for i:=l1+2 to x2 do

  b[x2-i]:=ord(s[i])-48;

  if l2>l1 then p:=true

  else if l2=l1 then

  begin

  i:=l1;

  while (i>0)and(a[i]=b[i]) do dec(i);

  if a[i]<b[i] then p:=true;

  end;

  if p then

  begin

  for i:=1 to l2 do c[i]:=b[i]-a[i];

  for i:=1 to l2 do

  if c[i]<0 then

  begin

  c[i]:=c[i]+10;

  dec(c[i+1]);

  end;

  i:=l2;

  while c[i]=0 do dec(i);

  write('-');

  for l2:=i downto 1 do write(c[i]);

  writeln;

  end

  else

  begin

  for i:=1 to l1 do c[i]:=a[i]-b[i];

  for i:=1 to l1 do

  if c[i]<0 then

  begin

  c[i]:=c[i]+10;

  dec(c[i+1]);

  end;

  i:=l1;

  while c[i]=0 do dec(i);

  for l1:=i downto 1 do write(c[i]);

  writeln;

  end;

  end.


冷月寒笙
冷月寒笙
个性签名:生活就像海洋,只有强者才能到达彼岸。不畏艰难,勇往直前,成就卓越人生。

C语言高精度加法

你输入的是字符哦!!应该把字符转为数字再运算,然后你那两个循环的转换有什么作用??
我随便帮改了下!!不过其他输入方面的错误和浮点数的考虑我没加上!!自己想想吧!!
#include
#include
#include

char a[500], b[500];
int c[501];
void strfun ( char *p, int min, int max );//靠右对齐两个字符串

int main()
{
int la, lb, i, j, m;

gets (a);
gets (b);

la = strlen (a);
lb = strlen (b);

if ( la > lb )
strfun ( b, lb, la );

else if ( la < lb )
strfun ( a, la, lb );

m = la > lb ? la : lb;

for ( i = m; i >= 0; --i )
{
c[i] += (a[i] - '0') + (b[i] - '0');
if( c[i] > 9 )
{
c[i] = c[i] - 10;
c[i-1]++;
}
}
if ( c[i] == 1 )
putchar ('1');

for( i = 0; i < m; i++ )
printf("%d", c[i]);

putchar ('\n');

system ("PAUSE");
return 0;
}

void strfun ( char *p, int min, int max )//靠右对齐两个字符串
{
int i, j, k;
k = max - min;
for ( i = max, j = min; i >= 0; --i, --j )
{
if ( i >= k )
*(p + i) = *(p + j);
else *(p + i) = '0';
}
}


冷月寒笙
冷月寒笙
个性签名:生活就像海洋,只有强者才能到达彼岸。不畏艰难,勇往直前,成就卓越人生。

求大牛纠错c语言程序(有关高精度加减法)

/*********************
程序功能:计算任意位两整数相减
这里我为了程序的可管理性(也就是可维护性)
用了把程序分成了好几块,
当然对我来说这并不算多。这样的程序
更符合软件工程的要求或说对做比较大的程序较好
虽然这么多还是不够的,但是怕多了你会觉得太过复杂
请耐心读完,或直接上机器看结果。
当然对于有小数的也可以写,但是那样代码多得多。
******************/
#define LEN 250
#include
#include
/*A、B异号*/
int subA(char cha[], char chb[], char chc[])
{
int j = 0;
int tem = 0;
int flag = 0;
int a;
int b;
int fa = 0;
int fb = 0;
int lena = strlen(cha) - 1;
int lenb = strlen(chb) - 1;
char ch;
printf("not the same\n");
if ('-' == cha[0])
{
ch = '-';
fb = -1;
}
else
{
fa = -1;
ch = '+';
}
for (; lena > fa && lenb > fb; lena--, lenb--)
{
tem = (cha[lena] - '0') + (chb[lenb] - '0') + flag;
if (tem > 9)
{
flag = tem / 10;
tem %= 10;
}
else
{
flag = 0;
}
chc[j] = tem + '0';
j++;
}
if (lena > fa)
{
for (; lena > fa; lena--, j++)
{
tem = cha[lena] - '0' + flag;
if (tem > 9)
{
flag = tem / 10;
tem %= 10;
}
else
{
flag = 0;
}
chc[j] = tem + '0';
}
}
else if (lenb > fb)
{
for (; lenb > fb; lenb--, j++)
{
tem = chb[lenb] - '0' + flag;
if (tem > 9)
{
flag = tem / 10;
tem %= 10;
}
else
{
flag = 0;
}
chc[j] = tem + '0';
}
}
if (flag)
{
chc[j] = flag + '0';
j++;
}
chc[j] = ch;
j++;
return j;
}

/*比较函数*/
/****写这函数是因为发现用系统比较strcmp()出问题,具体在哪我也没去查
我当然也知道系统的会返回一些正负或0值,但是我这里测有时候对有时候错****/
int AcmpB(char cha[], char chb[])
{
int i;
int j;
int lena;
int lenb;
lena = strlen(cha);
lenb = strlen(chb);
if (lena > lenb)
{
return 1;
}
else if (lena < lenb)
{
return -1;
}
else
{
for (i = 0; i < lena; i++)
{
if (cha[i] < chb[i])
{
return -1;
}
else if (cha[i] > chb[i])
{
return 1;
}
}
}
}

/*A、B同号*/
int subB(char cha[], char chb[], char chc[])
{
int i;
int j = 0;
int f;
int tem;
int tema;
int temb;
int lena;
int lenb;
int count = 0;
int temflag;
char ch;
char chtem[LEN];
if ('-' == cha[0])
{
ch = '-';
f = 0;
}
else
{
f = -1;
ch = '+';
}
temflag = AcmpB(cha, chb);
/*调整长度*/
if (temflag < 0)
{
strcpy(chtem, cha);
strcpy(cha, chb);
strcpy(chb, chtem);
/*判断正负*/
if ('-' == ch)
{
f = 0;
ch = '+';
}
else
{
f = -1;
ch = '-';
}
}
lena = strlen(cha) - 1;
lenb = strlen(chb) - 1;
for (; lenb > f; lenb--, lena--)
{
tema = cha[lena];
temb = chb[lenb];
if (tema < temb)
{
for (i = lena - 1; i > f; i--)
{
if ('0' != cha[i])
{
cha[i] = ((cha[i] - '0') - 1) + '0';
break;
}
else
{
count++;
}
}
if (count)
{
for (i++; i 0; i++, count--)
{
cha[i] = '9';
}
}

tema += 10;
}
tem = tema - temb;
chc[j] = tem + '0';
j++;
}
/**退出循环有可能A还有数据**/
for (;lena > f; lena--)
{
chc[j] = cha[lena];
j++;
}
chc[j] = ch;
j++;
chc[j] = '\0';
return j;
}

/*判断输入的是否为合法数据,为程序健壮性设计,可不要。
但要保证你输入的是合法的,这是我规定的,合法返回1否则返回0
注意:这里判断的标准为正数不带符号,负数带减号且正数不能以0打头
负数也不能写成如-0123,而是写成-123否则将造成后面的大改AcmpB比较出错*/
int isringht(char ch[])
{
int i;
int len = strlen(ch);
/***这个if是防止输入如-0123类似数据****/
if ('-' == ch[0] && '0' == ch[1])
{
return 0;
}
if ('-' == ch[0] || '0' < ch[0] && ch[0] <= '9')
{
for (i = 1; i < len; i++)
{
if (ch[i] > '9' || ch[i] < '0')
{
return 0;
}
}
if (len == i)
{
return 1;
}
}
else
{
return 0;
}
}
/*输入函数这里规定如果输入不合法(含有非数字,除了符号位)
时,重输入,直到正确,当然还可以设别的出口,如果再加别的可能这程序会过大*/
void input(char ch[])
{
int flag = 1;
while (flag)
{
printf("Input the numbers:\n");
gets(ch);
if (!isringht(ch))
{
printf("Input error !\nplease re_input:\n");
}
else
{
flag = 0;
}
}
}
/*输出结果*/
void print(char ch[], int n)
{
int i;
int count = 0;
int flag = 1;
/*如果结果为零则直接输出一个0,而不是输出一串0*/
for (i = 0; i < n - 1; i++)
{
if ('0' != ch[i])
{
break;
}
}
if (i == n - 1)
{
printf("0");
return;
}
/****修正输出,比如当有-0003时只输出-3,正数也类似*****/
for (i = n - 2 - count; i >= 0; i--)
{
if ('0' == ch[i] && 1 == flag)
{
count++;
}
else
{
flag = 0;
break;
}
}
if ('+' == ch[n-1])
{
for (i = n - 2 - count; i >=0; i--)
printf("%c", ch[i]);
}
else
{
for (i = n - 1; i >= 0; i--)
{
printf("%c", ch[i]);
}
}
}

void main()
{
int i;
int len;
char ch;
char cha[LEN];
char chb[LEN];
char chresult[LEN + 1];/*结果可能有进位,如负数减正数*/

for (i = 0; i < LEN; i++) /*初始化存放结果的数组,以保证结果的正确性*/
{
chresult[i] = '0';
}
chresult[i] = '\0';/*字符串结束标志,本这不用多说*/

input(cha);
printf("the first number is: ");
puts(cha);
input(chb);
printf("the second number is: ");
puts(chb);
if ('-' == cha[0] && '-' != chb[0]|| '-' != cha[0] && '-' == chb[0])
{
ch = 'A';/*A、B异号*/
}
else
{
ch = 'B';/*A、B同号*/
}
switch(ch)
{
case 'A':
{
len = subA(cha, chb, chresult);
break;
}
case 'B':
{
len = subB(cha, chb, chresult);
break;
}
/* default:printf("*********"); */
}

printf("(first number sub second number)result is :\n");
print(chresult, len);
/*puts(chresult);
让程序到此停顿*/
getch();
}/***由于时间有限没有进行那么全面的测试,如果发现有什么漏处请给出指示
这样的代码你认为没有水平我也没办法了.等以后有提高再再次改进吧,现在能缩的只能这样了,不过一定能再缩的,不过那样会费更多的心思,要想出更好的算法**/