#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???
大数取余、大数比较、大数相加(更新中)
最新推荐文章于 2022-04-20 09:50:06 发布