wangarc 发表于 2024-9-18 18:55

大数加法之无符号加法

本段测试程序是人肉直接输入参数。也可以用以下函数获得:
1. 判断字符串是否为一个有效的数

本段程序需要调用以下函数:
1. 两个十进制字符相加得到十进制字符的结果和进位



int add_ip_dp(char * str1, int dot_pos1, int i_qty1, int d_qty1,
                          char * str2, int dot_pos2, int i_qty2, int d_qty2,
                          char * str3, int str3_array_size, int * offset);
/*add_ip_dp() return 1 if no error, otherwise 0
*add integral part and decimal part (str3 = str1 + str2)
*dot_pos: index of str where '.' located for decimal number
*                                                        or '\0' located for integral number.
*        i_qty: integral number quantity (integral part length)
*        d_qty: decimal number quantity (decimal part length)
*        str3: array to store result
*        str3_array_size: array size
*        offset: result will start from here (this function write result from tail to head)
*/

int main(void) //testing
{
        char * s1 = "0";
        char * s2 = "99999999999999999999";
        char * s3 = ".00000000000000000001";
        char * s4 = "1.00";
        char * s5 = "3.14159";
        char * s6 = "0003.14159000";
        char * s7 = "9999999999.9999999999";
        char str;
        int i, r;
        r = add_ip_dp(s1, 1, 1, 0, s2, 20, 20, 0, str, 128, &i);
        printf("\nreturn %d, offset = %d,\n%s + %s = %s\n", r, i, s1, s2, str + i);
        r = add_ip_dp(s2, 20, 20, 0, s3, 0, 0, 20, str, 128, &i);
        printf("\nreturn %d, offset = %d,\n%s + %s = %s\n", r, i, s2, s3, str + i);
        r = add_ip_dp(s3, 0, 0, 20, s4, 1, 1, 2, str, 128, &i);
        printf("\nreturn %d, offset = %d,\n%s + %s = %s\n", r, i, s3, s4, str + i);
        r = add_ip_dp(s4, 1, 1, 2, s5, 1, 1, 5, str, 128, &i);
        printf("\nreturn %d, offset = %d,\n%s + %s = %s\n", r, i, s4, s5, str + i);
        r = add_ip_dp(s5, 1, 1, 5, s6, 4, 4, 8, str, 128, &i);
        printf("\nreturn %d, offset = %d,\n%s + %s = %s\n", r, i, s5, s6, str + i);
        r = add_ip_dp(s6, 4, 4, 8, s7, 10, 10, 10, str, 128, &i);
        printf("\nreturn %d, offset = %d,\n%s + %s = %s\n", r, i, s6, s7, str + i);
        return 0;
}

int add_ip_dp(char * str1, int dot_pos1, int i_qty1, int d_qty1,
                          char * str2, int dot_pos2, int i_qty2, int d_qty2,
                          char * str3, int str3_array_size, int * offset)
{
        //return 1 = no error, 0 = fail.
        char * p1 = str1 + dot_pos1;        // p1 is a pointer to '.' or '\0' of str1
        char * p2 = str2 + dot_pos2;        // p2 is a pointer to '.' or '\0' of str2
        int i = str3_array_size;                // i is an index of str3, copy to *offset finally
        char carry = '0';                                // carry is a carry
        char c1, c2, c3;                                // c1, c2 and c3 are temp chars
        int k, j;                                                // k and j are temp index
       
        // set '\0' at the end of str3
        if (--i >= 0)
                str3 = '\0';
        else
                return 0;        //Error: insufficient space in str3

        // add decimal part: from tail to head
        k = (d_qty1 > d_qty2) ? d_qty1 : d_qty2;
        while (k > 0)
        {
                c1 = (k > d_qty1) ? '0' : p1;
                c2 = (k > d_qty2) ? '0' : p2;
                if (0 == dec_char_add(carry, c1, c2, &carry, &c3))
                        return 0;                //Error: return error from dec_char_add()
               
                if (--i >= 0)
                        str3 = c3;
                else
                        return 0;                //Error: insufficient space in str3
               
                if (str3 == '\0' && str3 == '0')
                        i++;                        //ignore '0' in the end of decimal
               
                --k;
        }
       
        // put a '.' in the string
        if (str3 != '\0')
        {
                if (--i >= 0)
                        str3 = '.';
                else
                        return 0;                //Error: insufficient space in str3
        }

        // add integral part: from tail to head
        k = 1;
        j = (i_qty1 > i_qty2) ? i_qty1 : i_qty2;
        while (k <= j)
        {
                c1 = (k > i_qty1) ? '0' : p1[-k];
                c2 = (k > i_qty2) ? '0' : p2[-k];
                if (0 == dec_char_add(carry, c1, c2, &carry, &c3))
                        return 0;                //Error: return error from dec_char_add()
               
                if (--i >= 0)
                        str3 = c3;
                else
                        return 0;                //Error: insufficient space in str3
               
                ++k;
        }

        // consider carry after last dec_char_add()
        if (carry == '1')
        {
                if (--i >= 0)
                        str3 = '1';
                else
                        return 0;                //Error: insufficient space in str3
        }

        // ignore all begining '0' in the string
        while (str3 == '0')
                ++i;

        // add a '0' if start with a '.'
        if (str3 == '.')
        {
                if (--i >= 0)
                        str3 = '0';
                else
                        return 0;                //Error: insufficient space in str3
        }

        // add a '0' if empty string
        if (str3 == '\0')
        {
                if (--i >= 0)
                        str3 = '0';
                else
                        return 0;                //Error: insufficient space in str3
        }

        // set *offset for str3
        *offset = i;
        return 1;        //Done
}

jacklemona 发表于 2024-9-18 19:12

感谢分享~
页: [1]
查看完整版本: 大数加法之无符号加法