首先是字符串翻转函数,大数相加、相减和相乘中都用到了这个函数
- /*
- ** 字符串翻转
- */
- void Reverse(char *str, int n)
- {
- int i;
- for (i = 0; i < n / 2; i++)
- {
- char tmp;
- tmp = str[i];
- str[i] = str[n-i-1];
- str[n-i-1] = tmp;
- }
- }
1.大数相加
- /*
- ** 这里假设str1和str2表示的数为非负数
- */
- void BigNumAdd(char *str1, char *str2, char *result)
- {
- if (str1 == NULL || str2 == NULL || result == NULL)
- {
- return;
- }
- int len1, len2;
- len1 = strlen(str1);
- len2 = strlen(str2);
- Reverse(str1, len1); // 将str1翻转
- Reverse(str2, len2); // 将str2翻转
- int weight = 0; // 表示进位
- int sum = 0;
- int index = 0; // 表示result的下标,从0开始,相加结束后应翻转
- int i, j;
- i = 0; // 表示str1的下标
- j = 0; // 表示str2的下标
- while (i < len1 && j < len2) // 两个数对应的每一位进行相加
- {
- sum = str1[i] - '0' + str2[j] - '0' + weight;
- weight = sum / 10; // 计算是否要进位
- sum %= 10;
- result[index++] = sum + '0';
- i++;
- j++;
- }
- while (i < len1) // str2已经加完了,这时还要考虑str1和str2的最高位相加时是否有进位的情况
- {
- sum = str1[i] - '0' + weight;
- weight = sum / 10;
- sum %= 10;
- result[index++] = sum + '0';
- i++;
- }
- while (j < len2) // str1已经加完了,这时还要考虑str1和str2的最高位相加时是否有进位的情况
- {
- sum = str2[j] - '0' + weight;
- weight = sum / 10;
- sum %= 10;
- result[index++] = sum + '0';
- j++;
- }
- if (weight > 0) // str1和str2都已经加完了,这时还要考虑最后一步中是否产生了进位
- {
- result[index++] = weight + '0';
- }
- result[index] = '\0';
- Reverse(result, index); // 对result进行翻转,得到最终的结果
- }
- /*
- ** 这里假设str1和str2表示的数为非负数,并且str1表示的数大于等于str2的数
- */
- void BigNumMinus(char *str1, char *str2, char *result)
- {
- if (str1 == NULL || str2 == NULL || result == NULL)
- {
- return;
- }
- int len1, len2;
- len1 = strlen(str1);
- len2 = strlen(str2);
- Reverse(str1, len1); // 将str1翻转
- Reverse(str2, len2); // 将str2翻转
- int index = 0; // 表示result的下标,从0开始,相减结束后应翻转
- int i, j;
- i = 0; // 表示str1的下标
- j = 0; // 表示str2的下标
- while (i < len1 && j < len2) // 两个数对应的每一位进行相减
- {
- result[index] = (str1[i] - '0') - (str2[j] - '0');
- if (result[index] < 0) // 当str1对应的位小于str2对应的位,应借位
- {
- result[index] = result[index] + 10 + '0';
- str1[i+1] = str1[i+1] - 1;
- }
- else
- {
- result[index] = result[index] + '0';
- }
- index++;
- i++;
- j++;
- }
- while (i < len1) // str2已减完,但是可能存在借位的情况
- {
- result[index] = str1[i] - '0';
- if (result[index] < 0)
- {
- result[index] = result[index] + 10 + '0';
- str1[i+1] = str1[i+1] - 1;
- }
- else
- {
- result[index] = result[index] + '0';
- }
- index++;
- i++;
- }
- while (result[--index] == '0') // 去掉result后面的'0' 如40000 - 39999时会存在一些多源的'0'字符
- ;
- result[++index] = '\0';
- Reverse(result, index); // 对result进行翻转,得到最终的结果
- }
3.大数相乘
- /*
- ** 这里假设str1和str2表示的数为非负数,并且str1表示的数大于等于str2的数
- */
- void BigNumMulti(char *str1, char *str2, char *result)
- {
- if (str1 == NULL || str2 == NULL || result == NULL)
- {
- return;
- }
- if (strcmp(str1, "0") == 0 || strcmp(str2, "0") == 0)
- {
- strcpy(result, "0");
- return;
- }
- int len1, len2;
- len1 = strlen(str1);
- len2 = strlen(str2);
- Reverse(str1, len1); // 将str1翻转
- Reverse(str2, len2); // 将str2翻转
- memset(result, '0', N);
- int i, j;
- int multiFlag; // 乘积进位
- int addFlag; // 加法进位
- for (i = 0; i < len2; i++) // str2的每一位
- {
- multiFlag = 0;
- addFlag = 0;
- for (j = 0; j < len1; j++) // str1的每一位
- {
- int temp1 = (str2[i] - '0') * (str1[j] - '0') + multiFlag;
- multiFlag = temp1 / 10;
- temp1 = temp1 % 10;
- int temp2 = (result[i+j] - '0') + temp1 + addFlag;
- addFlag = temp2 / 10;
- result[i+j] = temp2 % 10 + '0';
- }
- result[i + len1] += multiFlag + addFlag;
- }
- if (result[len1+len2-1] == '0')
- {
- result[len1+len2-1] = '\0';
- }
- else
- {
- result[len1+len2] = '\0';
- }
- Reverse(result, strlen(result)); // 对result进行翻转,得到最终的结果
- }