From 5aa12235e6b02f9f1231426258c9c6867718e6fa Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Thu, 7 Mar 2024 20:49:14 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=8A=A0=E6=B3=95=E8=BF=90=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/common_errno.h | 5 +- include/common_interface.h | 12 +++++ src/common_interface.c | 94 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/include/common_errno.h b/include/common_errno.h index edb8c77..97eb18c 100644 --- a/include/common_errno.h +++ b/include/common_errno.h @@ -9,4 +9,7 @@ #define COM_MEM_LESS 0x0002 /* < 内存资源紧张,无法申请内存 */ #define COM_BUF_SMALL 0x0003 /* < buffer太小,请更换大的buffer */ #define COM_ERR_LENGTH 0x0004 /* < 文件长度过长,应当小于256个字符 */ -#define COM_ERR_FILE_NOT_EXISTS 0x0005 /* < 文件不存在 */ \ No newline at end of file +#define COM_ERR_FILE_NOT_EXISTS 0x0005 /* < 文件不存在 */ + +#define COM_BIG_NUMBER_OUT_BUF_SMALL 0x0100 /* < 存放结果的buff太小,无法装下整个运算结果 */ +#define COM_BIG_NUMBER_NOT_NUMBER 0x0101 /* < 输入的数字字符串非法 */ \ No newline at end of file diff --git a/include/common_interface.h b/include/common_interface.h index 4f8bfcc..b780dab 100644 --- a/include/common_interface.h +++ b/include/common_interface.h @@ -181,4 +181,16 @@ int common_byte_8_set(uint64_t *in, common_byte_type byte_type, int position); */ int common_byte_8_get(uint64_t *in, common_byte_type *byte_type, int position); +/** + * @brief 大数加法 + * + * @param out[out] 运算结果 + * @param olen[out] 结果长度 + * @param out_size[in] buffer大小 + * @param left[in] 左操作数 + * @param right[in] 右操作数 + * @return int + */ +int common_big_number_plus(char *out, int *olen, int out_size, const char left[], const char right[]); + #endif \ No newline at end of file diff --git a/src/common_interface.c b/src/common_interface.c index 3da2995..76276c9 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -6,6 +6,7 @@ #include #include #include +#include #define COMMON_SIZE_UINT32_T 4 //范围 #define COMMON_PATH_MAX 256 //路径最大长度 @@ -195,3 +196,96 @@ int common_byte_8_get(uint64_t *in, common_byte_type *byte_type, int position) { return COM_OK; } + +static int check_str_is_number(const char number[]) { + int length = strlen(number); + int i = 0; + for(i = 0; i < length; i++) { + if(number[i] < '0' || number[i] > '9') { + return 0; + } + } + return 1; +} + +int common_big_number_plus(char *out, int *olen, int out_size, const char left[], const char right[]) { + int length_left = 0, length_right = 0; // 左右运算数长度 + char *temp = NULL; + int temp_size = 0; + int i = 0, j = 0; + int ret = COM_BAD_INPUT; + + if(out == NULL || olen == NULL || left == NULL || right == NULL) { // 输入检测 + return COM_BAD_INPUT; + } + + if((!check_str_is_number(left)) || (!check_str_is_number(right))) { // 数字是否合法检测 + return COM_BIG_NUMBER_NOT_NUMBER; + } + + length_left = strlen(left); + length_right = strlen(right); + + if(out_size < length_left || out_size < length_right) { // buffer太小,无法装下运算结果 + return COM_BIG_NUMBER_OUT_BUF_SMALL; + } + + // 申请内存空间 + if(length_left > length_right) { + temp_size = length_left + 1; + } + else { + temp_size = length_right + 1; + } + temp = (char *)malloc(sizeof(char) * temp_size); + memset(temp, '0', temp_size); + + // 从后向前拷贝left + for(i = temp_size - 1, j = length_left - 1; i >= 0 && j >= 0; i--, j--) { + temp[i] = left[j]; + } + + // 从后向前进行加法运算并包含进位 + for(i = temp_size - 1, j = length_right - 1; i >= 0 && j >= 0; i--, j--) { + temp[i] = temp[i] + (right[j] - '0'); + if(temp[i] > '9') { + temp[i - 1]++; + temp[i] = (temp[i] % ('9' + 1)) + '0'; + } + } + + // 判断计算结果是否超过了out的大小 + if(temp[0] == '0') { + if(temp_size - 1 > out_size) { + ret = COM_BIG_NUMBER_OUT_BUF_SMALL; + goto exit; + } + } + else { + if(temp_size > out_size) { + ret = COM_BIG_NUMBER_OUT_BUF_SMALL; + goto exit; + } + } + + // 找到第一个非0位 + i = 0; + j = 0; + while(temp[i] == '0') { + i++; + } + // 赋值长度 + *olen = temp_size - i; + // 向out中进行赋值 + for(; i < temp_size; i++, j++) { + out[j] = temp[i]; + } + + ret = COM_OK; + +exit: + if(temp != NULL) { + free(temp); + temp = NULL; + } +} \ No newline at end of file -- Gitee From ae469ae82d8fbb662fd6af32f0c866aa06962ba9 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Thu, 7 Mar 2024 20:50:07 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=8A=A0=E6=B3=95=E8=BF=90=E7=AE=97=E7=9A=84demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demos/big_number.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 demos/big_number.c diff --git a/demos/big_number.c b/demos/big_number.c new file mode 100644 index 0000000..e09454e --- /dev/null +++ b/demos/big_number.c @@ -0,0 +1,21 @@ +#include +#include + +#include "common_errno.h" +#include "common_interface.h" + +int main() { + char result[1024] = { 0 }; + int olen = 0; + + char left[] = "1111111111"; + char right[] = "9111111111"; + + int ret = 0; + + ret = common_big_number_plus(result, &olen, sizeof(result), left, right); + printf("ret is %d\n", ret); + printf("%s\n", result); + + return 0; +} \ No newline at end of file -- Gitee From 9dc9daf364106b95ba7c85d01c9bf64998012cc2 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Sat, 9 Mar 2024 17:29:34 +0800 Subject: [PATCH 03/12] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=87=8F=E6=B3=95=E6=8E=A5=E5=8F=A3=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/common_interface.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/include/common_interface.h b/include/common_interface.h index b780dab..cf5a572 100644 --- a/include/common_interface.h +++ b/include/common_interface.h @@ -189,8 +189,20 @@ int common_byte_8_get(uint64_t *in, common_byte_type *byte_type, int position); * @param out_size[in] buffer大小 * @param left[in] 左操作数 * @param right[in] 右操作数 - * @return int + * @return #COM_OK 操作成功 */ int common_big_number_plus(char *out, int *olen, int out_size, const char left[], const char right[]); +/** + * @brief 大数减法 + * + * @param out[out] 运算结果 + * @param olen[out] 结果长度 + * @param out_size[in] buffer大小 + * @param left[in] 左操作数 + * @param right[in] 右操作数 + * @return #COM_OK 操作成功 + */ +int common_big_number_subtraction(char *out, int *olen, int out_size, const char left[], const char right[]); + #endif \ No newline at end of file -- Gitee From 4550d8aae2f77fcdf3dafeb350bcf92e20b78499 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Mon, 11 Mar 2024 13:45:59 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=87=8F=E6=B3=95=E7=9A=84=E5=A3=B0=E6=98=8E=E5=92=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/common_errno.h | 4 +- src/common_interface.c | 121 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/include/common_errno.h b/include/common_errno.h index 97eb18c..c7efcff 100644 --- a/include/common_errno.h +++ b/include/common_errno.h @@ -12,4 +12,6 @@ #define COM_ERR_FILE_NOT_EXISTS 0x0005 /* < 文件不存在 */ #define COM_BIG_NUMBER_OUT_BUF_SMALL 0x0100 /* < 存放结果的buff太小,无法装下整个运算结果 */ -#define COM_BIG_NUMBER_NOT_NUMBER 0x0101 /* < 输入的数字字符串非法 */ \ No newline at end of file +#define COM_BIG_NUMBER_NOT_NUMBER 0x0101 /* < 输入的数字字符串非法 */ + +#define COM_ERR_UNKNOWN 0xffff /* < 不应该发生的错误,未知错误 */ \ No newline at end of file diff --git a/src/common_interface.c b/src/common_interface.c index 76276c9..627bbb2 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -208,6 +208,40 @@ static int check_str_is_number(const char number[]) { return 1; } +// 从低到高开始运算,直接从最后一位开始 +static void internal_subtraction(char *out, int *olen, int osize, const char left[], int left_size, const char right[], int right_size) { + int counter = osize - 1; + int l = left_size - 1; + int r = right_size - 1; + int flag = 0; // 借位标志,0没有借位,1借位 + while(l >= 0 && r >= 0 && counter >= 0) { + if(flag == 1) { // 发生借位 + if(left[l] - 1 >= right[r]) { + out[counter] = '0' + left[l] -1 - right[r]; + flag = 0; + } + else { + out[counter] = '0' + 10 + left[l] -1 - right[r]; + flag = 1; + } + } + else { // 未发生借位 + if(left[l] >= right[r]) { + out[counter] = '0' + left[l] - right[r]; + flag = 0; + } + else { + out[counter] = '0' + 10 + left[l] - right[r]; + flag = 1; + } + } + counter--; + l--; + r--; + } + *olen = osize; +} + int common_big_number_plus(char *out, int *olen, int out_size, const char left[], const char right[]) { int length_left = 0, length_right = 0; // 左右运算数长度 char *temp = NULL; @@ -288,4 +322,91 @@ exit: free(temp); temp = NULL; } + return ret; +} + +/** + * 大数减法算法思想: + * 1. 先判断运算结果的正负性 + * 2. 从低位到高位依次进行减法运算,此时需要加入符号 + * 3. 去除前导零 +*/ +int common_big_number_subtraction(char *out, int *olen, int out_size, const char left[], const char right[]) { + int length_left = 0, length_right = 0; // 左右运算数长度 + char *temp = NULL; + int temp_size = 0; + int i = 0, j = 0; + int ret = COM_BAD_INPUT; + + char *big = NULL, *small = NULL; + + // 1代表left大,2代表right大 + int which = 0; + + if(out == NULL || olen == NULL || left == NULL || right == NULL) { // 输入检测 + return COM_BAD_INPUT; + } + + if((!check_str_is_number(left)) || (!check_str_is_number(right))) { // 数字是否合法检测 + return COM_BIG_NUMBER_NOT_NUMBER; + } + + length_left = strlen(left); + length_right = strlen(right); + + if(out_size < length_left + 1 || out_size < length_right + 1) { // buffer太小,无法装下运算结果 + return COM_BIG_NUMBER_OUT_BUF_SMALL; + } + + // step1: 比较两个数字的大小 + // 位数长的大 + if(length_left > length_right) { + which = 1; + } + else if(length_left < length_right) { + which = 2; + } + // 位数相等则比较每一位 + for(i = 0; i < length_left; i++) { + if(left[i] > right[i]) { + which = 1; + } + else if(left[i] < right[i]) { + which = 2; + } + } + // 如果which == 0则代表两数相等,可以返回结果 + if(which == 0) { + out[0] = '0'; + *olen = 1; + return COM_OK; + } + + memset(out, '0', out_size); + + // step2: 从低位到高位依次进行减法运算,可以向高位进行借位运算 + if(which == 1) { // 左边大,直接传入 + internal_subtraction(out, olen, out_size, left, length_left, right, length_right); + j = 0; + } + else if(which == 2) { // 右边大,调换位置传入,并将第一位设置为-号 + internal_subtraction(out, olen, out_size, right, length_right, left, length_left); + out[0] = '-'; + j = 1; + } + else { + return COM_ERR_UNKNOWN; + } + + // step3: 去除前导0 + i = 0; + while(out[i] == '0' || out[i] == '-') { + i++; + } + for(;j < *olen && i < *olen; j++, i++) { + out[j] = out[i]; + } + *olen = j; + + return COM_OK; } \ No newline at end of file -- Gitee From ddee5498a2588887429814cd5d3426de5f519884 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Mon, 11 Mar 2024 13:46:19 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=87=8F=E6=B3=95=E7=9A=84demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demos/big_number.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/demos/big_number.c b/demos/big_number.c index e09454e..6ad1537 100644 --- a/demos/big_number.c +++ b/demos/big_number.c @@ -1,5 +1,6 @@ #include #include +#include #include "common_errno.h" #include "common_interface.h" @@ -14,8 +15,22 @@ int main() { int ret = 0; ret = common_big_number_plus(result, &olen, sizeof(result), left, right); + result[olen] = '\0'; printf("ret is %d\n", ret); printf("%s\n", result); + memset(result, 0, sizeof(result)); + + ret = common_big_number_subtraction(result, &olen, sizeof(result), left, right); + result[olen] = '\0'; + printf("ret is %d\n", ret); + printf("%s\n", result); + memset(result, 0, sizeof(result)); + + ret = common_big_number_subtraction(result, &olen, sizeof(result), right, left); + result[olen] = '\0'; + printf("ret is %d\n", ret); + printf("%s\n", result); + memset(result, 0, sizeof(result)); return 0; } \ No newline at end of file -- Gitee From 341934a85de32a3813ecb8cc2bf758dce5eade5f Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Mon, 11 Mar 2024 14:19:13 +0800 Subject: [PATCH 06/12] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E6=95=B0=E5=AD=97=E6=A3=80=E6=9F=A5=E9=99=90=E5=AE=9A=E8=8C=83?= =?UTF-8?q?=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common_interface.c b/src/common_interface.c index 627bbb2..83291ba 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -201,7 +201,7 @@ static int check_str_is_number(const char number[]) { int length = strlen(number); int i = 0; for(i = 0; i < length; i++) { - if(number[i] < '0' || number[i] > '9') { + if(!((number[i] >= '0' && number[i] <= '9') || (number[i] == '-' || number[i] == '+'))) { return 0; } } -- Gitee From 2ba39f23e7b7104d2ea953b32d7065d069fc22b1 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Wed, 13 Mar 2024 09:59:38 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E4=B9=98=E6=B3=95=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/common_interface.h | 12 +++++ src/common_interface.c | 93 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/include/common_interface.h b/include/common_interface.h index cf5a572..7c8d306 100644 --- a/include/common_interface.h +++ b/include/common_interface.h @@ -205,4 +205,16 @@ int common_big_number_plus(char *out, int *olen, int out_size, const char left[] */ int common_big_number_subtraction(char *out, int *olen, int out_size, const char left[], const char right[]); +/** + * @brief 大数乘法 + * + * @param out[out] 运算结果 + * @param olen[out] 结果长度 + * @param out_size[in] buffer大小 + * @param left[in] 左操作数 + * @param right[in] 右操作数 + * @return #COM_OK 操作成功 + */ +int common_big_number_multiplication(char *out, int *olen, int out_size, const char left[], const char right[]); + #endif \ No newline at end of file diff --git a/src/common_interface.c b/src/common_interface.c index 83291ba..47065e0 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -408,5 +408,98 @@ int common_big_number_subtraction(char *out, int *olen, int out_size, const char } *olen = j; + return COM_OK; +} + +/** + * 大数乘法算法思想: + * 1. out_size >= (strlen(left) > strlen(right) ? strlen(left) : strlen(right)) * 2 ? 进行下一步 : return COM_BIG_NUMBER_OUT_BUF_SMALL + * 2. 判断结果的正负性 + * 3. 开始按位进行乘法运算,要记住偏移位数,直接存放到out中 + * 4. 将数字转换成字符串 + * 5. 处理前导零 + * 6. 赋值olen + */ +int common_big_number_multiplication(char *out, int *olen, int out_size, const char left[], const char right[]) { + int length_left = 0, length_right = 0; + int i = 0, j = 0; + int ret = COM_BAD_INPUT; + // 正负性,0是负数,1是正数 + int is_positive = 0; + // 偏移量,用于乘法计算 + int move = 0; + // 输出数组base + int out_base = 0; + // 中间结果 + int *temp = NULL; + + if(out == NULL || olen == NULL || left == NULL || right == NULL) { // 输入检测 + return COM_BAD_INPUT; + } + + if(!check_str_is_number(left) || !check_str_is_number(right)) { // 数字是否合法检测 + return COM_BIG_NUMBER_NOT_NUMBER; + } + + length_left = strlen(left); + length_right = strlen(right); + + // step1: 判断buffer + if(out_size < length_left * 2 || out_size < length_right * 2) { // buffer太小 + return COM_BIG_NUMBER_OUT_BUF_SMALL; + } + + // step2: 判断正负性 + if((left[0] != '-' && right[0] != '-') || (left[0] == '-' && left[0] == '-')) { + is_positive = 1; + } + else { + is_positive = 0; + } + + // 申请内存 + temp = (int *)malloc(sizeof(int) * out_size); + memset(temp, 0, sizeof(int) * out_size); + // 赋值base + out_base = out_size - 1; + + // step3: 按位进行乘法运算 + for(i = length_left - 1; i >= 0 && out_base >= 0; i--, out_base--) { + for(j = length_right - 1; j >= 0; j--) { + temp[out_base + length_right - j - 1] += ((int)left[i] - '0') * ((int)right[j] - '0'); + } + } + + // step4: 处理数字进位 + for(i = out_size - 1; i >= 0; i--) { + int base = 0; + int current = temp[i]; + temp[i] = 0; + while(current != 0) { + temp[i + base] = current % 10; + current = current / 10; + base++; + } + } + + // step5: 去除前导零 + i = 0; + if(is_positive == 0) { + out[0] = '-'; + i = 1; + } + j = 0; + while(temp[j] == 0) { + j++; + } + + for(; j < out_size && i < out_size; j++, i++) { + out[i] = temp[j] + '0'; + } + + *olen = i; + + free(temp); + return COM_OK; } \ No newline at end of file -- Gitee From a458eb24e1c3e12736ba13349624a355eb960221 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Wed, 13 Mar 2024 09:59:53 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E4=B9=98=E6=B3=95demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demos/big_number.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/demos/big_number.c b/demos/big_number.c index 6ad1537..909f626 100644 --- a/demos/big_number.c +++ b/demos/big_number.c @@ -9,8 +9,8 @@ int main() { char result[1024] = { 0 }; int olen = 0; - char left[] = "1111111111"; - char right[] = "9111111111"; + char left[] = "123"; + char right[] = "222"; int ret = 0; @@ -32,5 +32,11 @@ int main() { printf("%s\n", result); memset(result, 0, sizeof(result)); + ret = common_big_number_multiplication(result, &olen, sizeof(result), left, right); + result[olen] = '\0'; + printf("ret is %d\n", ret); + printf("%s\n", result); + memset(result, 0, sizeof(result)); + return 0; } \ No newline at end of file -- Gitee From 0159018139e9a1aa16a1d11ba2ce0f90f6eb9835 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Fri, 15 Mar 2024 17:49:03 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=8A=A0=E6=B3=95=E8=BF=90=E7=AE=97=EF=BC=8C=E8=80=83=E8=99=91?= =?UTF-8?q?=E8=BF=9B=E5=B8=A6=E7=AC=A6=E5=8F=B7=E6=95=B0=E5=AD=97=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common_interface.c | 419 +++++++++++++++++++++++++++++++++-------- 1 file changed, 341 insertions(+), 78 deletions(-) diff --git a/src/common_interface.c b/src/common_interface.c index 559087e..b7433f4 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -12,6 +12,28 @@ #define COMMON_SIZE_UINT32_T 4 //范围 #define COMMON_PATH_MAX 256 //路径最大长度 +// 内部布尔类型 +typedef enum { + COMMON_BOOL_FALSE, + COMMON_BOOL_TRUE, + COMMON_BOOL_MAX, +}common_bool; + +// 数字正负性 +typedef enum { + COMMON_OPERATE_NEGATIVE, + COMMON_OPERATE_POSITIVE, + COMMON_OPERATE_MAX, +}common_operate; + +// 数字大小比较 +typedef enum { + COMMON_COMPARE_BIGGER, + COMMON_COMPARE_SMALLER, + COMMON_COMPARE_EQUAL, + COMMON_COMPARE_MAX, +}common_compare; + /** * 判断大小端 */ @@ -198,7 +220,8 @@ int common_byte_8_get(uint64_t *in, common_byte_type *byte_type, int position) { return COM_OK; } -static int check_str_is_number(const char number[]) { +// 检查一个输入大数是否为合法数字 +static int internal_check_str_is_number(const char number[]) { int length = strlen(number); int i = 0; for(i = 0; i < length; i++) { @@ -209,52 +232,251 @@ static int check_str_is_number(const char number[]) { return 1; } -// 从低到高开始运算,直接从最后一位开始 -static void internal_subtraction(char *out, int *olen, int osize, const char left[], int left_size, const char right[], int right_size) { - int counter = osize - 1; - int l = left_size - 1; - int r = right_size - 1; - int flag = 0; // 借位标志,0没有借位,1借位 - while(l >= 0 && r >= 0 && counter >= 0) { - if(flag == 1) { // 发生借位 - if(left[l] - 1 >= right[r]) { - out[counter] = '0' + left[l] -1 - right[r]; - flag = 0; - } - else { - out[counter] = '0' + 10 + left[l] -1 - right[r]; - flag = 1; - } +// 内部加法算法,左加右,不考虑符号 +static int internal_plus(char *out, int *olen, int osize, const char left[], int length_left, const char right[], int length_right) { + int *result = NULL; + int result_size = length_left > length_right ? length_left + 1 : length_right + 1; + int result_count = 0; + int ret = COM_OK; + + int left_number = 0; + int right_number = 0; + int l = 0, r = 0; + + int i; + + int temp = 0; + + result = (int *)malloc(sizeof(int) * result_size); + if(result == NULL) { + ret = COM_MEM_LESS; + goto exit; + } + memset(result, 0, sizeof(int) * result_size); + + l = length_left - 1; + r = length_right - 1; + result_count = 0; + + // 赋值给int数组 + while(result_count < result_size && (l >= 0 || r >= 0)) { + left_number = 0; + right_number = 0; + // 拿到数字 + if(l >= 0) { + left_number = left[l] - '0'; + l--; + } + if(r >= 0) { + right_number = right[r] - '0'; + r--; } - else { // 未发生借位 - if(left[l] >= right[r]) { - out[counter] = '0' + left[l] - right[r]; - flag = 0; + result[result_count] = left_number + right_number; + result_count++; + } + + // 从前向后进行进位操作 + for(i = 0; i < result_count && i < result_size; i++) { + if(result[i] >= 10) { + result[i + 1] += result[i] / 10; + result[i] %= 10; + if(i == result_count - 1) { + result_count++; } - else { - out[counter] = '0' + 10 + left[l] - right[r]; - flag = 1; + } + } + + // 从后向前赋值给out数组 + temp = 0; + for(i = result_count - 1; i >= 0 && temp < result_size; i--) { + out[temp] = result[i] + '0'; + temp++; + } + *olen = temp; + +exit: + if(result != NULL) { + free(result); + } + return ret; + +} + +// 内部减法算法,左减右,不考虑符号,左操作数一定是大于右操作数 +static int internal_subtraction(char *out, int *olen, int osize, const char left[], int left_size, const char right[], int right_size) { + int ret = COM_OK; + int *result = NULL; + int result_count = 0; + int result_size = left_size > right_size ? left_size : right_size; + + int i = 0; + int temp = 0; + + int l = 0, r = 0; + int number_left = 0, number_right = 0; + + result = (int *)malloc(sizeof(int) * result_size); + if(result == NULL) { + ret = COM_MEM_LESS; + goto exit; + } + memset(result, 0, sizeof(int) * result_size); + internal_debug("result init ok\n"); + + // 将两个操作数,直接left - right存放到result中,尽管会有负数,但是后面能够统一处理 + result_count = 0; + l = left_size - 1; + r = right_size - 1; + while(result_count < result_size && (l >= 0 || r >= 0)) { + number_left = 0; + number_right = 0; + if(l >= 0) { + number_left = left[l] - '0'; + l--; + } + if(r >= 0) { + number_right = right[r] - '0'; + r--; + } + result[result_count] = number_left - number_right; + result_count++; + } + + // 一次遍历,消除掉所有的借位情况 + for(i = 0; i < result_count; i++) { + if(result[i] < 0) { + result[i] += 10; + result[i + 1] --; + if(i == result_count - 1 && result[i + 1] == 0) { + result_count--; } } - counter--; - l--; - r--; + internal_debug("%d\n", result[i]); + } + + // 一次遍历,复制到out中 + temp = 0; + for(i = result_count - 1; i >= 0 && temp < osize; i--) { + out[temp] = result[i] + '0'; + temp++; + } + *olen = temp; + internal_debug("%d\n", temp); + ret = COM_OK; + +exit: + if(result != NULL) { + free(result); } - *olen = osize; + return ret; } +// 比较两个大数的大小,bigger代表number1大,smaller代表number2大,equal代表两者相等 +static common_compare internal_compare(const char number1[], const char number2[]) { + char *head_number1 = NULL; + char *head_number2 = NULL; + + int length_number1 = 0; + int length_number2 = 0; + + int i = 0; + + int temp = 0; + while(!(number1[temp] >= '0' && number1[temp] <= '9')) { + temp++; + } + head_number1 = number1 + temp; + + temp = 0; + while(!(number2[temp] >= '0' && number2[temp] <= '9')) { + temp++; + } + head_number2 = number2 + temp; + + length_number1 = strlen(head_number1); + length_number2 = strlen(head_number2); + + if(length_number1 > length_number2) { + return COMMON_COMPARE_BIGGER; + } + if(length_number1 < length_number2) { + return COMMON_COMPARE_SMALLER; + } + + for(i = 0; i < length_number1; i++) { + if(head_number1[i] > head_number2[i]) { + return COMMON_COMPARE_BIGGER; + } + else if(head_number1[i] < head_number2[i]) { + return COMMON_COMPARE_SMALLER; + } + } + + return COMMON_COMPARE_EQUAL; +} + +// 去除前导零 +static void internal_clear_front_zero(char input[], int *olen) { + int length = *olen; + int counter = 0; + int i = 0; + while(input[i] == '0') { + i++; + } + for(; i < length; i++) { + input[counter] = input[i]; + counter++; + } + *olen = counter; +} + +// 获得符号 +common_operate internal_get_operate(const char number[]) { + if(number[0] == '-') { + return COMMON_OPERATE_NEGATIVE; + } + return COMMON_OPERATE_POSITIVE; +} + +/** + * 大数加法算法(带符号数字): +1. 输入判断 +2. 判断输入符号是否同号,同号视为相加,异号视为相减,使用common_bool is_same,true为同号,false为异号 + 2.1. 同号状态下,直接使用int走一遍即可,从后向前 + 2.1.1. 如果都是负号,则输出结果头带上负号 + 2.1.2. 修正完符号后进行加法计算 + 2.2. 异号状态下,视为减法运算 + 2.2.1. 如果左操作数为负号 + 2.2.1.1. 如果左操作数比右操作数大,调用公共减接口,结束后将结果赋值-号,结果为负数 + 2.2.1.2. 如果右操作数比左操作数大,调用公共减接口时需要调换顺序,结束后无需赋值符号,结果为正数 + 2.2.2. 如果右操作数为负号 + 2.2.2.1. 如果左操作数比右操作数大,调用公共减接口,结束后无需赋值符号,结果为正数 + 2.2.2.2. 如果右操作数比左操作数大,调用公共减接口时需要调换顺序,结束后赋值-号,结果为负数 + +*/ int common_big_number_plus(char *out, int *olen, int out_size, const char left[], const char right[]) { int length_left = 0, length_right = 0; // 左右运算数长度 - char *temp = NULL; - int temp_size = 0; int i = 0, j = 0; + int l = 0, r = 0; int ret = COM_BAD_INPUT; + char *head_left = NULL; + char *head_right = NULL; + int temp = 0; + + // 运算符 + common_operate operate_left = COMMON_OPERATE_MAX, operate_right = COMMON_OPERATE_MAX; + // 是否为同号 + common_bool is_same_operate = COMMON_BOOL_FALSE; + // 谁大谁小 + common_compare compare = COMMON_COMPARE_MAX; + + // step 1 输入判断 if(out == NULL || olen == NULL || left == NULL || right == NULL) { // 输入检测 return COM_BAD_INPUT; } - if((!check_str_is_number(left)) || (!check_str_is_number(right))) { // 数字是否合法检测 + if((!internal_check_str_is_number(left)) || (!internal_check_str_is_number(right))) { // 数字是否合法检测 return COM_BIG_NUMBER_NOT_NUMBER; } @@ -265,65 +487,106 @@ int common_big_number_plus(char *out, int *olen, int out_size, const char left[] return COM_BIG_NUMBER_OUT_BUF_SMALL; } - // 申请内存空间 - if(length_left > length_right) { - temp_size = length_left + 1; + // step 2 判断符号是否相同 + // 拿到符号 + operate_left = internal_get_operate(left); + operate_right = internal_get_operate(right); + + // 判断符号是否相同 + if(operate_left == operate_right) { + is_same_operate = COMMON_BOOL_TRUE; } else { - temp_size = length_right + 1; - } - temp = (char *)malloc(sizeof(char) * temp_size); - memset(temp, '0', temp_size); - - // 从后向前拷贝left - for(i = temp_size - 1, j = length_left - 1; i >= 0 && j >= 0; i--, j--) { - temp[i] = left[j]; + is_same_operate = COMMON_BOOL_FALSE; } - - // 从后向前进行加法运算并包含进位 - for(i = temp_size - 1, j = length_right - 1; i >= 0 && j >= 0; i--, j--) { - temp[i] = temp[i] + (right[j] - '0'); - if(temp[i] > '9') { - temp[i - 1]++; - temp[i] = (temp[i] % ('9' + 1)) + '0'; + + // step 2.1 同号视为相加 + if(is_same_operate == COMMON_BOOL_TRUE) { + if(operate_left == COMMON_OPERATE_NEGATIVE) { + internal_debug("operate is negative\n"); + ret = internal_plus(out + 1, olen, out_size - 1, left + 1, length_left - 1, right + 1, length_right - 1); + out[0] = '-'; + *olen = (*olen) + 1; } - } - - // 判断计算结果是否超过了out的大小 - if(temp[0] == '0') { - if(temp_size - 1 > out_size) { - ret = COM_BIG_NUMBER_OUT_BUF_SMALL; - goto exit; + else { + internal_debug("operate is positive\n"); + ret = internal_plus(out, olen, out_size, left, length_left, right, length_right); } + goto exit; } + // step 2.2 不同符号 else { - if(temp_size > out_size) { - ret = COM_BIG_NUMBER_OUT_BUF_SMALL; + internal_debug("start to compare\n"); + // 比较大小 + compare = internal_compare(left, right); + internal_debug("compare is %d\n", compare); + if(compare == COMMON_COMPARE_EQUAL) { + internal_debug("equal\n"); + out[0] = '0'; + *olen = 1; + ret = COM_OK; goto exit; } - } + internal_debug("compare ok\n"); - // 找到第一个非0位 - i = 0; - j = 0; - while(temp[i] == '0') { - i++; - } - // 赋值长度 - *olen = temp_size - i; - // 向out中进行赋值 - for(; i < temp_size; i++, j++) { - out[j] = temp[i]; + // 过滤掉符号的影响 + temp = 0; + while(!(left[temp] >= '0' && left[temp] <= '9')) { + temp++; + } + head_left = left + temp; + length_left -= temp; + internal_debug("temp = %d\n", temp); + + temp = 0; + while(!(right[temp] >= '0' && right[temp] <= '9')) { + temp++; + } + head_right = right + temp; + length_right -= temp; + internal_debug("temp = %d\n", temp); + + + // step 2.2.1 左操作数为负数 + if(operate_left == COMMON_OPERATE_NEGATIVE) { + // step 2.2.1.1 左操作数比右操作数大 + if(compare == COMMON_COMPARE_BIGGER) { + internal_debug("step 2.2.1.1\n"); + out[0] = '-'; + ret = internal_subtraction(out + 1, olen, out_size - 1, head_left, length_left, head_right, length_right); + *olen = (*olen) + 1; + goto exit; + } + // step 2.2.1.2 右操作数比左操作数大 + else { + internal_debug("step 2.2.1.2\n"); + ret = internal_subtraction(out, olen, out_size, head_right, length_right, head_left, length_left); + goto exit; + } + } + // step 2.2.2 右操作数为负数 + else if(operate_right == COMMON_OPERATE_NEGATIVE) { + // step 2.2.2.1 左操作数比右操作数大 + if(compare == COMMON_COMPARE_BIGGER) { + internal_debug("step 2.2.2.1\n"); + ret = internal_subtraction(out, olen, out_size, head_left, length_left, head_right, length_right); + goto exit; + } + // step 2.2.2.2 右操作数比左操作数大 + else { + internal_debug("step 2.2.2.2\n"); + out[0] = '-'; + ret = internal_subtraction(out + 1, olen, out_size - 1, head_right, length_right, head_left, length_left); + *olen = (*olen) + 1; + goto exit; + } + } } - ret = COM_OK; - exit: - if(temp != NULL) { - free(temp); - temp = NULL; - } + internal_clear_front_zero(out, olen); return ret; + } /** @@ -348,7 +611,7 @@ int common_big_number_subtraction(char *out, int *olen, int out_size, const char return COM_BAD_INPUT; } - if((!check_str_is_number(left)) || (!check_str_is_number(right))) { // 数字是否合法检测 + if((!internal_check_str_is_number(left)) || (!internal_check_str_is_number(right))) { // 数字是否合法检测 return COM_BIG_NUMBER_NOT_NUMBER; } @@ -438,7 +701,7 @@ int common_big_number_multiplication(char *out, int *olen, int out_size, const c return COM_BAD_INPUT; } - if(!check_str_is_number(left) || !check_str_is_number(right)) { // 数字是否合法检测 + if(!internal_check_str_is_number(left) || !internal_check_str_is_number(right)) { // 数字是否合法检测 return COM_BIG_NUMBER_NOT_NUMBER; } -- Gitee From aa5e2e47077497be6d8a5e6abb11a9b0d54499ed Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Mon, 18 Mar 2024 16:15:52 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=87=8F=E6=B3=95,=E5=A4=8D=E7=94=A8=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E5=8A=A0=E6=B3=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common_interface.c | 87 ++++++++++-------------------------------- 1 file changed, 21 insertions(+), 66 deletions(-) diff --git a/src/common_interface.c b/src/common_interface.c index b7433f4..d4acf0b 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -591,88 +591,43 @@ exit: /** * 大数减法算法思想: - * 1. 先判断运算结果的正负性 - * 2. 从低位到高位依次进行减法运算,此时需要加入符号 - * 3. 去除前导零 + * 1. 左操作数取反,调用大数加法即可 */ int common_big_number_subtraction(char *out, int *olen, int out_size, const char left[], const char right[]) { - int length_left = 0, length_right = 0; // 左右运算数长度 - char *temp = NULL; - int temp_size = 0; - int i = 0, j = 0; - int ret = COM_BAD_INPUT; - - char *big = NULL, *small = NULL; - - // 1代表left大,2代表right大 - int which = 0; + int length = 0; + int i = 0; + int ret = 0; - if(out == NULL || olen == NULL || left == NULL || right == NULL) { // 输入检测 + if(right == NULL) { return COM_BAD_INPUT; } - if((!internal_check_str_is_number(left)) || (!internal_check_str_is_number(right))) { // 数字是否合法检测 - return COM_BIG_NUMBER_NOT_NUMBER; - } - - length_left = strlen(left); - length_right = strlen(right); + length = strlen(right); - if(out_size < length_left + 1 || out_size < length_right + 1) { // buffer太小,无法装下运算结果 - return COM_BIG_NUMBER_OUT_BUF_SMALL; + if(length <= 0) { + return COM_BAD_INPUT; } - // step1: 比较两个数字的大小 - // 位数长的大 - if(length_left > length_right) { - which = 1; - } - else if(length_left < length_right) { - which = 2; - } - // 位数相等则比较每一位 - for(i = 0; i < length_left; i++) { - if(left[i] > right[i]) { - which = 1; - } - else if(left[i] < right[i]) { - which = 2; - } - } - // 如果which == 0则代表两数相等,可以返回结果 - if(which == 0) { - out[0] = '0'; - *olen = 1; - return COM_OK; - } + char *temp = (char *)malloc(sizeof(char) * (length + 5)); - memset(out, '0', out_size); + memset(temp, 0, length + 5); - // step2: 从低位到高位依次进行减法运算,可以向高位进行借位运算 - if(which == 1) { // 左边大,直接传入 - internal_subtraction(out, olen, out_size, left, length_left, right, length_right); - j = 0; - } - else if(which == 2) { // 右边大,调换位置传入,并将第一位设置为-号 - internal_subtraction(out, olen, out_size, right, length_right, left, length_left); - out[0] = '-'; - j = 1; + if(right[0] == '-') { + for(i = 1; i < length; i++) { + temp[i - 1] = right[i]; + } } else { - return COM_ERR_UNKNOWN; + temp[0] = '-'; + for(i = 0; i < length; i++) { + temp[i + 1] = right[i]; + } } - // step3: 去除前导0 - i = 0; - while(out[i] == '0' || out[i] == '-') { - i++; - } - for(;j < *olen && i < *olen; j++, i++) { - out[j] = out[i]; - } - *olen = j; + ret = common_big_number_plus(out, olen, out_size, left, temp); - return COM_OK; + free(temp); + return ret; } /** -- Gitee From 64194f7b3fad03418c564c81514c505c972ed82c Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Mon, 18 Mar 2024 16:24:25 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E9=80=9A=E8=BF=87=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demos/list.c | 9 ++++----- src/common_interface.c | 13 ++++--------- src/list.c | 1 - test/check_interface.c | 4 ++-- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/demos/list.c b/demos/list.c index 4b46111..115ff14 100644 --- a/demos/list.c +++ b/demos/list.c @@ -11,7 +11,6 @@ int main() { int i = 0; int *temp = NULL; int8_t size = 0; - int get = 0; ret = list_init(&handler); if(ret != LIST_OK) { @@ -31,7 +30,7 @@ int main() { temp = NULL; - ret = list_size(handler, &size); + ret = list_size(handler, (int64_t *)&size); if(ret != LIST_OK) { printf("list get isze error, code: 0x%04x\n", ret); goto exit; @@ -39,7 +38,7 @@ int main() { printf("list size is %d\n", size); for(i = 0; i < 10; i++) { - ret = list_get_at(handler, i + 1, &temp); + ret = list_get_at(handler, i + 1, (void **)&temp); if(ret != LIST_OK) { printf("list get error, code: 0x%04x\n", ret); goto exit; @@ -55,7 +54,7 @@ int main() { goto exit; } for(i = 0; i < 9; i++) { - ret = list_get_at(handler, i + 1, &temp); + ret = list_get_at(handler, i + 1, (void **)&temp); if(ret != LIST_OK) { printf("list get error, code: 0x%04x\n", ret); goto exit; @@ -73,7 +72,7 @@ int main() { goto exit; } for(i = 0; i < 10; i++) { - ret = list_get_at(handler, i + 1, &temp); + ret = list_get_at(handler, i + 1, (void **)&temp); if(ret != LIST_OK) { printf("list get error, code: 0x%04x\n", ret); goto exit; diff --git a/src/common_interface.c b/src/common_interface.c index 7a85033..4171a18 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -378,8 +378,8 @@ exit: // 比较两个大数的大小,bigger代表number1大,smaller代表number2大,equal代表两者相等 static common_compare internal_compare(const char number1[], const char number2[]) { - char *head_number1 = NULL; - char *head_number2 = NULL; + const char *head_number1 = NULL; + const char *head_number2 = NULL; int length_number1 = 0; int length_number2 = 0; @@ -461,12 +461,10 @@ common_operate internal_get_operate(const char number[]) { */ int common_big_number_plus(char *out, int *olen, int out_size, const char left[], const char right[]) { int length_left = 0, length_right = 0; // 左右运算数长度 - int i = 0, j = 0; - int l = 0, r = 0; int ret = COM_BAD_INPUT; - char *head_left = NULL; - char *head_right = NULL; + const char *head_left = NULL; + const char *head_right = NULL; int temp = 0; // 运算符 @@ -647,11 +645,8 @@ int common_big_number_subtraction(char *out, int *olen, int out_size, const char int common_big_number_multiplication(char *out, int *olen, int out_size, const char left[], const char right[]) { int length_left = 0, length_right = 0; int i = 0, j = 0; - int ret = COM_BAD_INPUT; // 正负性,0是负数,1是正数 int is_positive = 0; - // 偏移量,用于乘法计算 - int move = 0; // 输出数组base int out_base = 0; // 中间结果 diff --git a/src/list.c b/src/list.c index 518e8d6..8c1446f 100644 --- a/src/list.c +++ b/src/list.c @@ -255,7 +255,6 @@ int list_free_all(list **handler) { while(head != NULL) { if(head->data != NULL) { - int *t = head->data; free(head->data); } temp = head; diff --git a/test/check_interface.c b/test/check_interface.c index c4aa530..dfa8d03 100644 --- a/test/check_interface.c +++ b/test/check_interface.c @@ -4,7 +4,7 @@ int main() { SRunner *sr; - int number_failed = 0; + // int number_failed = 0; sr = srunner_create(check_base64()); srunner_add_suite(sr, check_byte()); @@ -13,7 +13,7 @@ int main() srunner_set_fork_status(sr, CK_NOFORK); srunner_run_all (sr, CK_VERBOSE); - number_failed = srunner_ntests_failed(sr); + // number_failed = srunner_ntests_failed(sr); srunner_free(sr); return 0; -- Gitee From 83e3c52dd3ba8474de41f899dfa605dd0574bfb9 Mon Sep 17 00:00:00 2001 From: bear <1248825327@qq.com> Date: Mon, 18 Mar 2024 18:13:53 +0800 Subject: [PATCH 12/12] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=A7=E6=95=B0?= =?UTF-8?q?=E4=B9=98=E6=B3=95=E7=9A=84=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common_interface.c | 78 ++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/src/common_interface.c b/src/common_interface.c index 4171a18..f71a704 100644 --- a/src/common_interface.c +++ b/src/common_interface.c @@ -646,11 +646,15 @@ int common_big_number_multiplication(char *out, int *olen, int out_size, const c int length_left = 0, length_right = 0; int i = 0, j = 0; // 正负性,0是负数,1是正数 - int is_positive = 0; + common_operate is_positive = COMMON_OPERATE_MAX; // 输出数组base int out_base = 0; // 中间结果 - int *temp = NULL; + int64_t *temp = NULL; + int ret = COM_BAD_INPUT; + + // 过滤掉符号位的指针 + const char *head_left = NULL, *head_right = NULL; if(out == NULL || olen == NULL || left == NULL || right == NULL) { // 输入检测 return COM_BAD_INPUT; @@ -670,55 +674,79 @@ int common_big_number_multiplication(char *out, int *olen, int out_size, const c // step2: 判断正负性 if((left[0] != '-' && right[0] != '-') || (left[0] == '-' && left[0] == '-')) { - is_positive = 1; + is_positive = COMMON_OPERATE_POSITIVE; } else { - is_positive = 0; + is_positive = COMMON_OPERATE_NEGATIVE; + } + + // 过滤掉符号 + i = 0; + while(left[i] < '0' || left[i] > '9') { + i++; } + head_left = left + i; + length_left -= i; + + i = 0; + while(right[i] < '0' || right[i] > '9') { + i++; + } + head_right = right + i; + length_right -= i; // 申请内存 - temp = (int *)malloc(sizeof(int) * out_size); - memset(temp, 0, sizeof(int) * out_size); + temp = (int64_t *)malloc(sizeof(int64_t) * out_size); + if(temp == NULL) { + ret = COM_MEM_LESS; + goto exit; + } + memset(temp, 0, sizeof(int64_t) * out_size); // 赋值base - out_base = out_size - 1; + out_base = 0; // step3: 按位进行乘法运算 - for(i = length_left - 1; i >= 0 && out_base >= 0; i--, out_base--) { + for(i = length_left - 1; i >= 0; i--) { for(j = length_right - 1; j >= 0; j--) { - temp[out_base + length_right - j - 1] += ((int)left[i] - '0') * ((int)right[j] - '0'); + temp[out_base + length_right - 1 - j] += (head_left[i] - '0') * (head_right[j] - '0'); } + out_base++; } + out_base += length_right - 1; // step4: 处理数字进位 - for(i = out_size - 1; i >= 0; i--) { - int base = 0; - int current = temp[i]; - temp[i] = 0; - while(current != 0) { - temp[i + base] = current % 10; - current = current / 10; - base++; + for(i = 0; i < out_base; i++) { + if(temp[i] >= 10) { + temp[i + 1] += temp[i] / 10; + temp[i] = temp[i] % 10; + if(i == out_base - 1) { + out_base++; + } } } - // step5: 去除前导零 + // step5: 复制到结果中 i = 0; - if(is_positive == 0) { + if(is_positive == COMMON_OPERATE_NEGATIVE) { out[0] = '-'; i = 1; } - j = 0; - while(temp[j] == 0) { - j++; + + for(j = 0; j < out_base; j++) { + internal_debug("%d\n", temp[j]); } - for(; j < out_size && i < out_size; j++, i++) { - out[i] = temp[j] + '0'; + for(j = 0; j < out_base; j++) { + out[i] = temp[out_base - 1 - j] + '0'; + i++; } *olen = i; + ret = COM_OK; + +exit: free(temp); - return COM_OK; + return ret; } \ No newline at end of file -- Gitee