大数取余、大数比较、大数相加(更新中)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
*********************************************************************
*							大数取余
* 过程:
*		从大数最高位开始,只要其大于除数 sor, 就取余。
*	 例如:123 % 4
*
*       1 < 4  t = 1
*       2      t = 1 * 10 + 2 = 12 > 4    t=t % 4=0
*       3      t= 0 * 100 + 3 = 3         t=t % 4=3
*
*    因此余数是3。
*********************************************************************
*/
#if 0
int mod(char* a, int sor)					//被除数: dividend    除数: divisor  商: trade  余数: remained
{
	int i = 0, temp = 0;
	while(*(a + i) != '\0')
	{
		temp += *(a + i) - '0';

		if(temp > 4)
			temp %= sor;

		temp *= 10;
		i++;
	}

	return temp / 10;
}

int main()
{
	printf("大数取余\n");
	printf("%d\n", mod("123", 4));
	return 0;
}
#endif

/*
*********************************************************************
*							大数比较(有理数)
*
*********************************************************************
*/
#if 1
int pisite(char* x, char* y)//小数点的位置
{
	int pix ,piy;

	if(strchr(x, '.') == NULL)//化为小数
		strcat(x, ".0");
	if(strchr(y, '.') == NULL)
		strcat(y, ".0");

	pix = strchr(x, '.') - x;// .的下表,就算是int型也不需要除以 sizeof(int)
	piy = strchr(y, '.') - y;

	int flag = pix > piy ? 0 : (pix == piy ? 1 : 2);
	switch(flag)
	{
		case 0 : return 0; break;//x整数部分较长
		case 1 : return 1; break;//x,y整数部分相等
		case 2 : return 2; break;//y整数部分较长
	}
}

void cmp(char* a, char* b)
{
	int flag;

	flag = (a[0] == '-' ? 0 : 3) + (b[0] == '-' ? 2 : 1);//注意需要时 (0,3),(2,1),旨在它们相加时为不同值

	switch(flag)
	{
		case 1 : printf("a<b\n"); break;//a-,b+
		case 5 : printf("a>b\n"); break;//a+,b-
		case 2 : {						//a-,a-
					switch(pisite(a, b))
					{
						case 0 : printf("a<b\n"); break;
						case 1 : strcmp(a, b) > 0 ? printf("a<b\n") : (strcmp(a, b) == 0 ? printf("a==b\n") : printf("a>b\n")); break;
						case 2 : printf("a>b\n"); break;
					}
				 }
				 break;
		case 4 : {						//a+,a+
					switch(pisite(a, b))
					{
						case 0 : printf("a>b\n"); break;
						case 1 : strcmp(a, b) > 0 ? printf("a>b\n") : (strcmp(a, b) == 0 ? printf("a==b\n") : printf("a<b\n")); break;
						case 2 : printf("a<b\n"); break;
					}
				 }
				break;
	}	
}			

int main()
{
	printf("大数比较(有理数)\n");
//	char *s1 = new char('0'), *s2 = new char('0');		//OJ不接受这种写法
	char s1[1010], s2[1010];							//OJ接受这种写法
	while(scanf("%s %s", s1, s2) && (strcmp(s1, "0") || strcmp(s2, "0")))
	{
		cmp(s1, s2);
	}
	return 0;
}
#endif

/*
*********************************************************************
*							大数加法(正整数)
*
*********************************************************************
*/
#if 0

#define MAX_LENGTH 1100

char* add(char* stra, char* strb)
{
//	char* ans = new char('0');			//要这样初始化ans,不能下面那样初始化,否则乱码,原因未明
	char ans[MAX_LENGTH + 10] = {'0'};	//如果要这样初始化,要想不乱码,需要在printf("%s\n", add("1234", "123"))前加printf("\n")或其他,原因未明
	int i, j, k;
	int numa[MAX_LENGTH], numb[MAX_LENGTH], result[MAX_LENGTH + 10];
	int lena = strlen(stra);
	int lenb = strlen(strb);
	int max_len = lena > lenb ? lena : lenb;

	memset(numa, 0, sizeof(numa));
	memset(numb, 0, sizeof(numb));
	memset(result, 0, sizeof(result));

	for(i = lena - 1, j = lenb - 1, k = 0; (i >= 0) || (j >= 0); i--, j--, k++) //numa, numb同时赋值并计算, 应该能减少一点浪费
	{
		if(i >= 0)
			numa[k] = stra[i] - '0';
		if(j >= 0)
			numb[k] = strb[j] - '0';

		result[k] += numa[k] + numb[k];			//注意,不是result[k] = numa[k] + numb[k]
		result[k + 1] += result[k] / 10;
		result[k] = result[k] % 10;				//注意,不是result[k] += result[k] % 10
	}

	int unlock = 0;
	for(i = k + 10, j = 0; i >= 0; i--)			//提前几位
	{
		if(result[i] != 0)						//消除前导0
			unlock = 1;			//解锁
		if(unlock)
		{
			*(ans + j) = result[i] + '0';
			j++;
		}
	}
	if(j == 0)									//0+0的情况
		j = 1;
	*(ans + j) = '\0';

	return ans;
}

int main()
{
	printf("大数加法(正整数)\n");
	int t, i;
//	char *a = new char('0'), *b = new char('0');//OJ不接受
	char a[MAX_LENGTH], b[MAX_LENGTH];
	scanf("%d", &t);
	for(i = 1; i <= t; i++)
	{
		scanf("%s %s", a, b);
		printf("Case %d:\n%s + %s = %s\n\n", i, a, b, add(a, b));
	}
	return 0;
}

#endif
// char *a = new char('0'), *b = new char('0');//OJ不接受                  WHY???
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值