忙里偷闲,终于完成了无限大整数相加算法的C语言代码,无限大整数相加算法的算法分析在这里。
500位的加法运行1000次,不打印结果的情况下耗时0.036秒,打印结果的情况下耗时16.285秒。
下面是源码:
#include <stdio.h> #include <stdlib.h> #include<string.h> #include <time.h> #define MAXNUM 1000000000000000000 /* 存储数据用的结构 long int型指针(Number)指向一个long int 数组,索引值最底的位, 为10进制数的最低18位。依次类推。 int型数值(Length)为数组的长度。 因为数组长度受int型最大值的限制,所以这个算法也不能真正实现“无限”。 */ struct BigInt{ long long* Number; int Length; }; void PrintBigInt(BigInt* bigNumber); long long pow(int x, int y); BigInt* MakeBigIntFromString(char* bigIntString); void DeleteBigInt(BigInt* bigNumber); BigInt* Add2BigInt(BigInt* n1, BigInt* n2); void main(){ char* numberStr = "99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999\0"; char* numberStr2 = "99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999\0"; BigInt* bn = MakeBigIntFromString(numberStr); BigInt* bn2 = MakeBigIntFromString(numberStr2); double tstart, tend, tcost; tstart = clock(); PrintBigInt(bn); PrintBigInt(bn2); for (int i = 0; i < 1000; i++){ BigInt* result = Add2BigInt(bn, bn2); //PrintBigInt(result); DeleteBigInt(result); } DeleteBigInt(bn); DeleteBigInt(bn2); tend = clock(); tcost = (double)(tend - tstart) / CLOCKS_PER_SEC; printf("%lf\n", tcost); } BigInt* Add2BigInt(BigInt* n1, BigInt* n2){ int maxLength = n1->Length; if (maxLength < n2->Length){ maxLength = n2->Length; } /* 加法只可能产生1位的进位,所以,只需要创建一个和最大长度相同的。 */ BigInt* nOut = (BigInt*)malloc(sizeof(BigInt)); nOut->Length = maxLength; nOut->Number = (long long*)malloc(sizeof(long long)* nOut->Length); for (int i = 0; i < nOut->Length; i++){ nOut->Number[i] = 0; } for (int i = 0; i < nOut->Length; i++){ if (n1->Length > i){ nOut->Number[i] += n1->Number[i]; } if (n2->Length > i){ nOut->Number[i] += n2->Number[i]; } /* 处理进位。最高位不需要处理。 */ if (i != (nOut->Length - 1)){ if (nOut->Number[i] >= MAXNUM){ nOut->Number[i] -= MAXNUM; nOut->Number[i + 1] = 1; } } } return nOut; } /* 从高到低显示数值 不考虑单个long long数据超出18位的情况。 */ void PrintBigInt(BigInt* bigNumber){ if (bigNumber == NULL){ return; } if (bigNumber->Length < 1){ return; } int length = bigNumber->Length - 1; for (int i = length; i >= 0; i--){ if (i != length){ if (bigNumber->Number[i] == 0){ printf("000000000000000000"); } else{ printf("%018lld", bigNumber->Number[i]); } } else{ if ((*bigNumber).Number[i] != 0){ printf("%lld", bigNumber->Number[i]); } } } printf("\n"); } /* 把字符串表示的数值格式化为BigInt型的结构 字符串结束位置用\0表示。 */ BigInt* MakeBigIntFromString(char* bigIntString){ /*获取字符串长度*/ int cLength = strlen(bigIntString); BigInt* outBigInt = (BigInt*)malloc(sizeof(BigInt)); if (cLength % 18 != 0){ outBigInt->Length = cLength / 18 + 1; } else{ outBigInt->Length = cLength / 18; } if (outBigInt->Length == 0){ outBigInt->Length == 1; outBigInt->Number = (long long *)malloc(sizeof(long long)); outBigInt->Number[0] = 0; return outBigInt; } outBigInt->Number = (long long *)malloc(sizeof(long long)* outBigInt->Length); for (int i = 0; i < outBigInt->Length; i++){ outBigInt->Number[i] = 0; } int powNum = 0; int numPos = 0; for (int i = cLength - 1; i >= 0; i--){ powNum = (cLength - 1 - i) % 18; numPos = (cLength - 1 - i) / 18; outBigInt->Number[numPos] += (bigIntString[i] - 48) * pow(10, powNum); } return outBigInt; } /* 简单的幂函数 x y 都必须为正整数 */ long long pow(int x, int y){ if (x == 0 || x < 0 || y < 0){ return 0; } if (x == 1 || y == 0){ return 1; } long long outNum = x; for (int i = 1; i < y; i++){ outNum = outNum * x; } return outNum; } void DeleteBigInt(BigInt* bigNumber){ if (bigNumber != NULL){ if (bigNumber->Number != NULL){ free(bigNumber->Number); } free(bigNumber); } }
时间: 2024-11-02 02:46:43