高精四则运算(含小数)

高精四则运算(正数)


  郑重声明:这篇博客是我的第一篇博客,那时候刚学C语言,所以有很大问题,但又不舍得删除。一年的总结发现,关于含有小数的高精运算其实基本上不会出现,所以只要掌握高精整数四则即可,今年大一结束,再次进行总结,请移步高精四则运算整数,谢谢~


一.正整数部分
(1)加法运算
(2)减法运算
(3)乘法运算
(4)除法运算
因为考虑到位数为上百位的大数会超过所有类型变量,故全部利用字符数组进行运算,以每一个单位存放一位数为思想,后对其进行进位处理,为了方便,全部采用倒序的方式,注意体会其好处
代码如下
(1)大数加法

#include <stdio.h>
#include <string.h>
#define N 1000
int main(void)
{
	char t[N+1] = {0}, a[N+1] = {0}, b[N+1] = {0};//定义数组并初始化 
	long int i, j, k, temp;//定义长整型变量确保后面累计相加在范围内 
	printf("请输入一个加数:\n");
	scanf("%s",t);//t字符数组用来接受未处理的字符串 
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  a[j++] = t[i] - '0';//对t字符数组进行倒序,并处理为"数字数组" 
	printf("请再输入一个加数:\n");
	scanf("%s",t);//同上 
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  b[j++] = t[i] - '0';
	for(i=0,k=0; i<N; i++)//a、b数组每一项进行相加,k表示进位 
	{
		temp = a[i] + b[i] + k;
		a[i] = temp % 10;
		k = temp / 10;
	}
	printf("加法计算结果为:\n");
	for(i=N; i>=0; i--)//倒序输出,恢复原位 
	  if(a[i] != 0)
	    for(; i>=0; i--)
		   printf("%d",a[i]);
	return 0;
} 

整数加法结果
(2)大数减法

#include <stdio.h>
#include <string.h>
#define N 1000 
int max(char a[],char b[],int x1,int x2);//max函数帮助判断"数字"a,b的大小 
int main(void)
{
	char t[N+1]={0}, a[N+1]={0}, b[N+1]={0};
	int i, j, k, m, x1, x2;
	printf("请输入被减数:\n");
   scanf("%s",t);
   x1 = strlen(t);
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  a[j++] = t[i] - '0';
	printf("请输入减数:\n");
	scanf("%s",t);
	x2 = strlen(t);
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  b[j++] = t[i] - '0';
	//上述部分与加法如出一辙,即:将数组倒序 
   m = max(a, b, x1, x2);
   printf("减法计算结果为:\n");
	if(m == 1)//a > b时,差 = a - b 
	{
		for(i=0,k=0; i<N; i++)
		{
			if(a[i]+k>=b[i])
			{
			  a[i] = a[i] - b[i] + k;
			  k = 0;
		   }
			else
		   {
			   a[i] = 10 + a[i] - b[i] + k;
			   k = -1;
		   }
		}
		for(i=N; i>=0; i--)
	     if(a[i] != 0)
	        for(; i>=0; i--)
	          printf("%d",a[i]);
	}
	else if(m == 0)//a < b时,差 = b - a; 
	{
		printf("-");
		for(i=0,k=0; i<N; i++)
		{
			if(b[i]+k>=a[i])
			{
				b[i] = b[i] - a[i] + k;
				k = 0;
			}
			else
			{
				b[i] = 10 + b[i] - a[i] + k;
				k = -1;
			}
		}
		for(i=N; i>=0; i--)
	     if(b[i] != 0)
	        for(; i>=0; i--)
	          printf("%d",b[i]);
	}
	else 
	  printf("0\n");
	return 0;
}
int max(char a[],char b[],int x1,int x2) 
{
	int i, m = 0;
	if(x1 > x2)
	  m = 1;
	else if(x1 == x2)
	{
		for(i=x1; i>=0; i--)
		{
		   if(a[i] > b[i])
		   {
		   	m = 1;
		   	break;
			}
			else if(a[i] < b[i])
			  break;
		}
		if(i == -1)
		  m = 2;
	}
	return m;
}

整数减法结果
(3)大数乘法

#include <stdio.h>
#include <string.h>
#define N 10000
int main(void)
{
	char t[N+1]={0}, a[N+1]={0}, b[N+1]={0};
	long int c[2*N+1]={0}, d[2*N+1]={0};
	int i, j, k, m, x1, x2;
	printf("请输入一个正整数:\n");
   scanf("%s",t);
   x1 = strlen(t);
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  a[j++] = t[i] - '0';
	printf("请输入另一个正整数:\n");
	scanf("%s",t);
	x2 = strlen(t);
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  b[j++] = t[i] - '0';//开始与之前两个一致
	for(i=0; i<x1; i++)
	  for(j=0; j<x2; j++)
	  	 c[i+j] += a[i]*b[j];
	for(i=m=0; i<2*N; i++)
	{
		c[i] += m;
		d[i] = c[i] % 10;
		m = c[i] / 10;
	}
	printf("乘法计算结果为:\n");
   for(i=2*N; i>=0; i--)
	  if(d[i] != 0)
	    for(; i>=0; i--)
		   printf("%d",d[i]);		   
	return 0;
}

整数乘法结果
(4)大数除法

#include <stdio.h>
#include <string.h>
#define N 1000
//注意!这种方法计算比较慢,当两数差距较大时
//核心思路:将除法运算化为减法运算 
int max(char a[],char b[]);
int main(void)
{
	char t[N+1]={0}, a[N+1]={0}, b[N+1]={0};
	long int c[N], d[N];
	int i, j, k, m, n = 0;
	printf("请输入被除数:\n");
   scanf("%s",t);
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  a[j++] = t[i] - '0';
	printf("请输入除数:\n");
	scanf("%s",t);
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  b[j++] = t[i] - '0';
   m = max(a,b);//开始与之前两个一致 
   while(m == 1)
   {
   	n++;
		for(i=0,k=0; i<N; i++)
		{
			if(a[i]+k>=b[i])
			{
			  a[i] = a[i] - b[i] + k;
			  k = 0;
		   }
			else
		   {
			  a[i] = 10 + a[i] - b[i] + k;
			  k = -1;
		   }
		}
      m = max(a,b);
	}
	printf("除法计算结果为:\n");
   if(m == 2)
     printf("%d\n", n+1);
	else
	{
		printf("商为:\n%d\n余数为:\n",n);
		for(i=N; i>=0; i--)
        if(a[i] != 0)
         for(; i>=0; i--)
           printf("%d",a[i]);
      printf("\n");
	}
  return 0;   
}
int max(char a[],char b[])
{
	int x1, x2, i, m = 0;
	for(i=N; i>=0; i--)
	  if(a[i] != 0)
	  {
	  	  x1 = i;
	  	  break;
	  }
	for(i=N; i>=0; i--)
	  if(b[i] != 0)
	  {
	  	  x2 = i;
	  	  break;
	  }
	if(x1 > x2)
	  m = 1;
	else if(x1 == x2)
	{
		for(i=x1; i>=0; i--)
		{
		   if(a[i] > b[i])
		   {
		   	m = 1;
		   	break;
			}
			else if(a[i] < b[i])
			  break;
		}
		if(i == -1)
		  m = 2;
	}
	return m;
}

整数除法结果
最后注意一点
本例中比较两个数大小,用到了自定义函数max,先比较位数即字符数组长度,谁长谁大,若相等长度,再比最高位,依次往低位进行比较。
思考🤔:
考虑max形参为什么不直接用两个数组如:int max(char a[], char b[]),然后在max函数里面用strlen()函数求出字符数组a和b的长度x1,x2
原因:
a, b数组是处理之后的数据,并非原始数据
例如:
刚开始输入t为100,,则a为001
然后再输入t为10,则b为01
这时候strlen(a)和strlen(b)相等
(因为处理之后字符0减去0的ascii码为’\0’,所以a数组和b数组里面能被strlen()函数测得的,只有1,所以a和b长度相等,实际上长度不等,001长度为3而01长度为2)
实际上100不等于10。所以max函数要有四个参数,字符数组长度x1,x2应在输入后(也就是倒序处理之前就应该计算长度)立即计算,也就解释了int max(char a[],char b[], int x1, int x2)中有四个参数的原因,也就是x1和x2不能在max函数内部计算。
二.带小数部分
(1)带小数的大数加法
(2)带小数的大数减法
(3)带小数的大数乘法
(4)带小数的大数除法
注 : 可以不带小数
代码如下
(1)思路: 对带小数的数(假设有小数)分开处理。没有小数的数,“小数部分”即整数后面不处理 。

#include <stdio.h>
#include <string.h>
#define N 1000
int max(int a, int b)
{
	return (a>b)? a:b;
}
int main(void)
{
	char t[N+1], a[N+1] = {0}, b[N+1] = {0};
	char c[N+1] = {0}, d[N+1] = {0};
	long int i, j, k, x1, x2, y1, y2, m, temp, flag = 0;
   scanf("%s", t);
	y1 = strlen(t) - 1;
	for(i=y1; i>=0; i--)
	  if(t[i] == '.')
	  {
	  	  x1 = i;
	  	  flag = 1;
	  }
	if(flag != 1)//判断是否带小数,如果没有小数,则无小数点,计算时不考虑小数部分 
	  x1 = y1 + 1;//就主动放弃对数组a的赋值,此时a里面全是0  
	for(j=0,i=x1-1; i>=0; i--)
	  a[j++] = t[i] - '0';
	for(j=0,i=x1+1; i<=y1; i++)
	  c[j++] = t[i] - '0';
//重复上面操作,完成两次输入 
	scanf("%s",t);
	y2 = strlen(t) - 1;
	for(i=y2; i>=0; i--)
	  if(t[i] == '.')
	  {
	     x2 = i;
	     flag = -1;
	  }
	if(flag != -1)
	  x2 = y2 + 1;
	for(j=0,i=x2-1; i>=0; i--)
	  b[j++] = t[i] - '0';
	for(j=0,i=x2+1; i<=y2; i++)
	  d[j++] = t[i] - '0';
	m = max(y1-x1,y2-x2);
//	printf("%d\n",m);     
	for(i=m, k=0; i>=0; i--)
	{
		temp = c[i] + d[i] + k;
	   c[i] = temp % 10;
		k = temp / 10;
	}
	if(k == 1)
	  a[0] += 1;
	for(i=0,k=0; i<N; i++)
	{
		temp = a[i] + b[i] + k;
		a[i] = temp % 10;
		k = temp / 10;
	}
	temp = 0;
	for(i=N; i>=0; i--)
	  if(a[i] != 0)
	    for(; i>=0; i--)
	    {
		   printf("%d",a[i]);
		   temp = 1;
		 }
	if(!temp)
	  printf("0");
	if(flag)
	  printf("%c",'.');
   for(i=0; i<m; i++)
	  printf("%d",c[i]);
	return 0;
} 

带小数加法结果
(2)思路:将两个数字的小数和整数(假设有小数),没有就不处理“小数部分”,即整数后不做处理

#include <stdio.h>
#include <string.h>
#define N 1000
int max_1(char a[], char b[], int x1, int x2);
int max_2(char c[], char d[], int n);
int max_len(int a, int b)
{
	return (a>b)? a:b;
}
int main(void)
{
	char t[N+1], a[N+1] = {0}, b[N+1] = {0};
	char c[N+1] = {0}, d[N+1] = {0};
	long int i, j, k, x1, x2, y1, y2, temp, m, n, flag = 0;
	scanf("%s",t);
	y1 = strlen(t) - 1;
	for(i=y1; i>=0; i--)
	  if(t[i] == '.')
	  {
	  	  x1 = i;
	  	  flag = 1;
	  }
	if(flag != 1)
	  x1 = y1 + 1;
	for(j=0,i=x1-1; i>=0; i--)
	  a[j++] = t[i] - '0';
	for(j=0,i=x1+1; i<=y1; i++)
	  c[j++] = t[i] - '0';
//重复上面操作,完成两次输入 
	scanf("%s",t);
	y2 = strlen(t) - 1;
	for(i=y2; i>=0; i--)
	  if(t[i] == '.')
	  {
	     x2 = i;
	     flag = -1;
	  }
	if(flag != -1)
	  x2 = y2 + 1;
	for(j=0,i=x2-1; i>=0; i--)
	  b[j++] = t[i] - '0';
	for(j=0,i=x2+1; i<=y2; i++)
	  d[j++] = t[i] - '0';
   m = max_1(a,b,x1,x2);
   n = max_len(y1-x1,y2-x2); 
   if(m == 2)
     m = max_2(c, d, n);
	if(m == 1) 
	{
		for(j=n,k=0; j>=0; j--)
		{
			if(c[j]+k>=d[j])
			{
			  c[j] = c[j] - d[j] + k;
			  k = 0;
		   }
			else
		   {
			  c[j] = 10 + c[j] - d[j] + k;
			  k = -1;
		   }
		}
		a[0] += k;
		for(i=0,k=0; i<N; i++)
		{
			if(a[i]+k>=b[i])
			{
			  a[i] = a[i] - b[i] + k;
			  k = 0;
		   }
			else
		   {
			  a[i] = 10 + a[i] - b[i] + k;
			  k = -1;
		   }
		}
		for(i=N; i>=0; i--)
        if(a[i] != 0)
          for(; i>=0; i--)
          {
		       k = 1;
             printf("%d",a[i]);
          }
	   if(!k)
	     printf("0");
	   if(flag)
	     printf("%c",'.');
	   for(j=0; j<n; j++)
	     printf("%d",c[j]);
	}
	else if(m == 0)
	{
		printf("-");
		for(j=n,k=0; j>=0; j--)
		{
			if(d[j]+k>=c[j])
			{
			  d[j] = d[j] - c[j] + k;
			  k = 0;
		   }
			else
		   {
			  d[j] = 10 + d[j] - c[j] + k;
			  k = -1;
		   }
		}
		b[0] += k;
		for(i=0,k=0; i<N; i++)
		{
			if(b[i]+k>=a[i])
			{
			  b[i] = b[i] - a[i] + k;
			  k = 0;
		   }
			else
		   {
			  b[i] = 10 + b[i] - a[i] + k;
			  k = -1;
		   }
		}
		for(i=N; i>=0; i--)
        if(b[i] != 0)
         for(; i>=0; i--)
         {
			  k = 1;
	        printf("%d",b[i]);
	      }
	   if(!k)
	     printf("0");
	   if(flag)
	     printf("%c",'.');
	   for(j=0; j<n; j++)
	     printf("%d",d[j]);
	}
	else
	  printf("0\n");	
	return 0;
}
//比较两个数组大小,保证差值为正 
int max_1(char a[], char b[], int x1, int x2)
{
	int i, m = 0;
	if(x1 > x2)
	  m = 1;
	else if(x1 == x2)
	{
		for(i=x1; i>=0; i--)
		{
		   if(a[i] > b[i])
		   {
		   	m = 1;
		   	break;
			}
			else if(a[i] < b[i])
			  break;
		}
	   if(i == -1)
		  m = 2;
	}
	return m;
}
int max_2(char c[], char d[], int n)
{
	int i, m = 0;
	if(n < 0)
	  m = 2;
	for(i = 0; i < n; i++)
	{
		if(c[i] > d[i])
		{
			m = 1;
			break;
		}
		else if(c[i] < d[i])
		{
			m = 0;
			break;
		}
	}
	if(i == n)
	  m = 2;
	return m;
}

带小数减法结果
(3)思路,将两个数除去小数点,变成整数乘以整数,再根据原来的两个小数小数位数保留小数。步骤如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 1000
int proces(char t[], int x)
{
	char *p;
	int i, j = 0, s = 0;
	p = &t[0];
	for(i=0; i<x; i++)
	{
	   if(p[i] == '.')
	   {
	      for(; i<x-1; i++)
	      {
	         p[i] = p[i+1];
	         s++;
	      }
	      if(s)
	        p[i] = '0';
	      break;
	   }
	}
	while(p[0] == '0'&&j < x)
	{
		for(i=0; i<x-1; i++)
		  p[i] = p[i+1];
		p[i] = '0';
		s++, j++;
	}
	if(j == x)
	{
	   printf("结果为:0   \n(你真无聊!)");
	   exit(0);
   }
	return s;
}
int main(void)
{
   char t[N+1]={0}, a[N+1]={0}, b[N+1]={0};
	long int c[2*N+1]={0}, d[2*N+1]={0};
	int i, j, k, x1, x2, s1, s2, m;
	printf("请输入一个数:\n");
   scanf("%s",t);
   x1 = strlen(t);
   s1 = proces(t, x1);
   if(s1)  s1++;
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  a[j++] = t[i] - '0';
	printf("请输入另一个数:\n");
	scanf("%s",t);
	x2 = strlen(t);
	s2 = proces(t, x2);
	if(s2)  s2++;
	s1 += s2;
//	printf("%d\n", s1);
	for(j=0,i=strlen(t)-1; i>=0; i--)
	  b[j++] = t[i] - '0';//开始与之前两个一致
	for(i=0; i<x1; i++)
	  for(j=0; j<x2; j++)
	  	 c[i+j] += a[i]*b[j];
	for(i=m=0; i<2*N; i++)
	{
		c[i] += m;
		d[i] = c[i] % 10;
		m = c[i] / 10;
	}
	printf("乘法计算结果为:\n");
   for(i=2*N; i>=0; i--)
   {
	  if(d[i] != 0)
	  {
	     for(; i>=s1; i--)
		    printf("%d",d[i]);
		  if(s1)  printf(".");
	     for(; i>=0; i--)
	       printf("%d",d[i]);	
		  break;
	  }
	  else if(i == s1)
	  {
	  	  printf("%d.", d[i]);
	  	  for(i--; i>=0; i--)
	  	    printf("%d", d[i]);
	  }
   }   
	return 0;
}

带小数乘法结果
(4) 思路同(3),将小数转换为整数,此时保证两个数扩大倍数相同,记住小数点后移位数(即扩大倍数),商与未处理前相同,只是余数扩大了,将余数处理,缩至原倍数。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 1000

int proces(char t[], int x); 
void dispos(char a[], char b[], int c);
int max(char a[], char b[]);//max函数帮助判断"数字"a,b的大小

int main(void)
{
   char t[N+1] = {0}, a[N+1] = {0}, b[N+1] = {0};
	int i, j, k, x1, x2, s1, s2, s, m, n = 0;
	
	printf("请输入一个数:\n");
   scanf("%s", t);
   x1 = strlen(t);
   s1 = proces(t, x1);
   if(s1)  s1++;
	for(j=0,i=x1-1; i>=0; i--)
	   a[j++] = t[i] - '0';
	   
	printf("请输入另一个数:\n");
	scanf("%s", t);
	x2 = strlen(t);
	s2 = proces(t, x2);
	if(s2)  s2++;
	for(j = 0,i = x2-1; i >= 0; i--)
	   b[j++] = t[i] - '0';//开始与之前两个一致
   dispos(a, b, s1-s2);
   s = (s1 > s2) ? s1 : s2;
   
   while (m = max(a, b))
   {
   	n ++; 
   	if(m == 1)//a > b时,差 = a - b 
		{
			for(i=0,k=0; i<N; i++)
			{
				if(a[i]+k>=b[i])
				{
				  a[i] = a[i] - b[i] + k;
				  k = 0;
			   }
				else
			   {
				   a[i] = 10 + a[i] - b[i] + k;
				   k = -1;
			   }
			}
		}
		else if(m == 2) 
		{
		   printf("商为:%d\n余数为:0\n", n);
		   break;
	   }
	}
	if(m == 0)
	{
	   printf("商为:%d\n余数为:", n);
	   for(i = N; i >= 0; i --)
	   {
	      if(a[i] != 0)
	      {
	      	if(i < s)
	      	  printf("0");
	         for(; i >= s; i --)
	            printf("%d",a[i]);
		      if(s)
		        printf(".");
		      for(; i >= 0; i --)
		        printf("%d",a[i]);
		      putchar('\n');
		   }
	   }
	}
   
	return 0;
}

int proces(char t[], int x)
{
	char *p;
	int i, j = 0, s = 0;
	p = &t[0];
	for(i=0; i<x; i++)
	{
	   if(p[i] == '.')
	   {
	      for(; i<x-1; i++)
	      {
	         p[i] = p[i+1];
	         s++;
	      }
	      if(s)
	        p[i] = '0';
	      break;
	   }
	}
	while(p[0] == '0'&& j < x)
	{
		for(i=0; i<x-1; i++)
		  p[i] = p[i+1];
		p[i] = '0';
		s++, j++;
	}
	if(j == x)
	{
	   printf("结果为0或者不存在!\n(你真无聊!)");
	   exit(0);
   }
	return s;
}

void dispos(char *a, char *b, int c)
{
	int i = N;
	if(c > 0)//b前插c个0;
	{
		 while(!b[i])
		   i--;
		 for(; i >=0; i--)
		   b[i+c] = b[i];
		 for(i = 0; i < c; i++)
		   b[i] = 0;
	}
	else if(c < 0)//a前插c个0;
	{
		 while(!a[i])
		   i--;
		 for(; i >=0; i--)
		   a[i-c] = a[i];
		 for(i = 0; i < -c; i++)
		   a[i] = 0;
	}
	
	return;
}

int max(char a[], char b[]) 
{
	int x1, x2, m, i, j;
	x1 = x2 = m = 0;
	i = j = N;
	while (!a[i])  i --;  
	  x1 = i;
	while (!b[j])  j --;
	  x2 = j;
	if(x1 > x2)  m = 1;
	else if (x1 == x2)
	{
		for(i = x1; i >= 0; i --)
		{
		   if(a[i] > b[i])
		   {
		   	m = 1;
		   	break;
			}
			else if(a[i] < b[i])
			  break;
		}
		if(i == -1)
		  m = 2;
	}
	return m;
}

运行结果 :
运行结果
运行结果
运行结果

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值