最近在看《挑战编程》的高精度,又学到了很多。但是,单从实用性来说,它的实现方式复杂了,而这里就要求更容易在比赛中实现的模版。
大数加法,请参照本博客的一篇题解。
大数减法:
void subtract_big(char *a, char *b, char *c){ int i, j, flag=0; int len1 = strlen(a), len2 = strlen(b); char *pmax = a, *pmin = b; memset(c, 0, sizeof(c)*max(len1, len2)+3); if(len2 > len1 || (len1 == len2 && strcmp(a, b) < 0)){ pmax = b; pmin = a; flag = 1; } len1 = strlen(pmax); len2 = strlen(pmin); for(i=len1-1, j=len2-1; i>=0; i--, j--){ if(j>=0) c[i+1] = pmax[i] - pmin[j] + '0'; else c[i+1] = pmax[i]; } if(flag) c[0] = '-'; for(i=len1; i>=1; i--) if(c[i] < '0'){c[i] += 10; c[i-1]--;} i = 1; while(c[i] == '0') i++; if(c[i] == '\0'){ c[0] = '0'; c[1] = '\0'; } else{ if(flag) j = 1; else j = 0; while(i<=len1){ c[j++] = c[i++]; } c[j] = '\0'; } }
大数乘除(这里除法并非大数除以大数):
#include <stdio.h> #include <string.h> #include <stdlib.h> void multiply_big(char *a, char *b, char *c){//大数乘法 int len1 = strlen(a), len2 = strlen(b), *s; int i, j; s = (int *)malloc(sizeof(int)*len1*len2); for(i=0; i<len1+len2; i++) s[i] = 0; for(i=0; i<len1; i++){ for(j=0; j<len2; j++){ s[i+j+1] += (a[i]-'0')*(b[j]-'0'); } } for(i=len1+len2-1; i>=1; i--){ if(s[i] >= 10){ s[i-1] += s[i] / 10; s[i] %= 10; } } i=0; while(s[i] == 0) i++; for(j=0; i<len1+len2; i++, j++) c[j] = s[i] + '0'; c[j] = '\0'; free(s); } int dividor_big(char *a, int b, char *c){ //大数除法,这里除数并非大数,返回余数 char *s; int tmp, i, j, len = strlen(a); s = (char *)malloc(sizeof(char)*(len+1)); tmp = 0; for(i=0; i<len; i++){ tmp = tmp*10+a[i]-'0'; s[i] = tmp / b + '0'; tmp %= b; } s[i] = '\0'; for(i=0; s[i] == '0' && s[i] != '\0'; i++); if(s[i] == '\0'){ c[0] = '0'; c[1] = '\0'; } else{ for(j=0; i<len; i++, j++) c[j] = s[i]; c[j] = '\0'; } free(s); return tmp; } int main(){ freopen("d:\\my.txt", "r", stdin); //char a[1000], b[1000], c[1000]; char a[1000], c[1000]; int b; //scanf("%s %s", a, b); scanf("%s %d", a, &b); // multiply_big(a, b, c); dividor_big(a, b, c); printf("%s\n", c); return 0; }