算法提高 实数相加

/* 问题描述
计算两个实数相加的结果。
输入的实数满足如下要求: (1) 小数点前的整数部分最多100位,(2) 小数点后的小数部分最多100位.
输入格式
两行字符串,每行都是一个合法的实数。合法的意思是指:
    整数部分的值如果大于零,则最高位数字必定大于零.
    如果整数部分的值为零,则整数部分只有一个零.
    小数部分尾部可以有任意多的零.
    可以没有小数部分,此时也没有小数点.
    如果有小数点, 则至少需要有一位小数部分, 且允许是零.
输出格式
相加结果。注意: 小数部分末尾如果有连续的0, 则它们都是有效数字, 不能舍去. 如果是两个整数相加, 则结果仍为整数而没有小数部分.
样例输入
样例一:
0.0000000000000000000000000000000000000111111111000000000000000000
100000000000000000000000000000000000000000000000000000.0
样例二:
3
4
样例三:
3.9
2
样例四:
1.00100000000000000000000
8.99999999999999999999999
样例输出
样例一:
100000000000000000000000000000000000000000000000000000.0000000000000000000000000000000000000111111111000000000000000000
样例二:
7
样例三:
5.9
样例四:
10.00099999999999999999999
0.0000000000000000000000000000000000000111111111000000000000000000
100000000000000000000000000000000000000000000000000000.01

 */

#include <stdio.h>
void shuru(int [], int [], int *, int*);
char sr_shu(int [] , int *);
void nixu( int [] , int );
void q_zshe(int [] , int , int [] , int , int [] , int * );
void q_xshe( int [] , int [] , int , int [] , int , int [] , int * );
void shuchu( int [] , int [] , int , int);
int main(void)
{
	int zs1[100]={0} , xs1[100]={0} , zsws1=0 ,xsws1=0;
	int zs2[100]={0} , xs2[100]={0} , zsws2=0 ,xsws2=0;
	shuru(zs1, xs1 , &zsws1 ,&xsws1);
	shuru(zs2, xs2 , &zsws2 ,&xsws2);
	int hezs[100]={0} , hexs[100]={0} , zsws3=0 ,xsws3=0;
	q_xshe(hezs, xs1 , xsws1 , xs2 , xsws2 , hexs , &xsws3);
	q_zshe(zs1 , zsws1 , zs2 , zsws2 , hezs , &zsws3);
	shuchu(hezs, hexs, xsws3 , zsws3 );
	return 0;
}
void shuchu( int zs[] , int xs[] , int xsws, int zsws)
{
	int i;
	for( i = zsws-1 ; i >=0 ; i--)
	{
		printf("%d",zs[i]);
	}
	if(xsws > 0 )
	{
		putchar('.');
		int i;
		for( i = 0 ; i < xsws ; i ++)
		{
			printf("%d",xs[i]);
		}
	}
	putchar('\n');
} 
void q_xshe(int zs[] ,int s1[] , int cd1, int s2[] , int cd2, int c[] , int * ws)
{
	int n=cd1 > cd2 ? cd1 : cd2;
	int i;
	for(i = 0 ; i < n ; i ++)
	{
		c[i]=s1[i]+s2[i];
	}
	for(i = n-1 ; i >0 ; i --)
	{
		c[i-1] += c[i]/10;
		c[i] %= 10;
		++ *ws;
	}
	if( n != 0)
	{
		++ *ws;
	}
	if(c[0] > 0)
	{
		zs[0] += c[0]/10;
		c[0] %= 10;
	}
} 
void q_zshe(int s1[] , int cd1, int s2[] , int cd2, int c[] , int * ws)
{
	int n=cd1 > cd2 ? cd1 : cd2;
	int i;
	for(i = 0 ; i < n ; i ++)
	{
		c[i]=c[i]+s1[i]+s2[i];
	}
	for(i = 0 ; i < n ; i ++)
	{
		c[i+1] += c[i]/10;
		c[i] %= 10;
		++ *ws;
	}
	if(c[n] > 0)
	{
		++ *ws;
	}
	
}
void nixu( int sz[] , int n)
{
	int tou=0 , wei = n-1;
	while(tou < wei)
	{
		int tmp=sz[tou];
		sz[tou]=sz[wei];
		sz[wei]=tmp;
		tou++;
		wei--;
	}
}
char sr_shu(int s[] , int * ws)
{
	char c;
	while((c = getchar()) != '.' && c != '\n' && c != EOF)
	{
		s[*ws] =  c - '0' ;
		++ *ws;
		
	}
	return c;
}
void shuru(int zs[], int xs[], int * zsws , int * xsws)
{
	if(sr_shu( zs , zsws) == '.')
	{
		sr_shu(xs , xsws);
	}
	nixu(zs , * zsws);
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 因为在计算机中,实数的表示是有限的,而且有精度限制。当一个很大的实数与一个很小的实数直接相加或相减时,可能会导致小数部分被截断或丢失,从而导致计算结果的误差变大。这种误差在一些计算中可能会产生严重的影响,因此应该尽量避免这种情况的出现。 ### 回答2: 将一个很大的实数与一个很小的实数直接相加或相减不仅容易出现精度误差,更容易导致结果偏差较大,影响计算的准确性。 首先,我们需要了解计算机处理实数时采用的是浮点数表示法。浮点数表示法使得计算机可以处理非常小或非常大的数字,但实数在计算机内部存储时只能存放有限的二进制位,而二进制和十进制在小数点后的位数并不完全一致,因此很多实数在计算机中并不能精确表示。在需要对浮点数进行运算的时候,计算机会对它们进行舍入,导致舍入产生的误差在某些情况下会累积。 其次,当一个很大的实数和一个很小的实数相加或相减的时候,计算机很容易在较小的实数值中失去精度,而这种精度损失会被扩大到和较大实数相加或相减的结果中。在这种情况下,实际结果可能会与预期结果有很大的偏差,甚至可能产生错误的结果。这是因为当一个表示非常小的实数和一个表示非常大的实数相加时,相加的结果可能只对大数产生很小的影响,但却扰动了小数的精度。 最后,应该避免将一个很大的实数和一个很小的实数直接相加或相减,需要利用数学工具和计算机编程语言中提供的高精度数值计算方法,以提高计算的准确性和避免数据误差带来的错误。 ### 回答3: 在计算机中,浮点数是通过有限的二进制位来表示的,因此浮点数有精度限制。这意味着在进行计算时,可能会出现舍入误差。当一个很大的实数与一个很小的实数直接相加或相减时,可能会导致精度损失的问题。 假设一个很大的实数和一个很小的实数相加,比如10^20和0.0001。由于计算机的精度限制,这两个数都需要进行舍入运算,舍入后得到的结果可能会是10^20。这个结果已经失去了相当多的精度,因为0.0001与10^20相比太小了,对结果的影响很小,但是由于计算机的精度限制,它的影响被夸大了,导致最终结果的精度明显降低。 同样地,如果一个很大的实数和一个很小的实数相减,比如10^20和0.0001,也可能会出现同样的问题。由于计算机的精度限制,两个数需要进行舍入运算,这可能会导致结果不准确。假如10^20和0.0001相减后得到的结果是1,这个结果可能是不准确的,因为0.0001与10^20相比太小了,在计算机中表示的时候可能被忽略掉了,导致最后结果的精度受到影响。 综上所述,应避免将一个很大的实数与一个很小的实数直接相加或相减,因为在计算过程中可能会出现精度损失的问题,导致最终结果的精度受到影响。为了避免这种情况,应该使用更精确的算法,比如高精度运算或者使用一些特殊的数值处理技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值