wangarc 发表于 2024-10-8 10:06

<ver0.2>大数计算加减乘除的字符实现

借着假期,把乘法和除法做完了,乘法用加法实现,除法用减法实现。这回四则运算都齐了,打算到此为止。

本来想的很简单的,结果函数越写越长,很多代码是重复的就直接复制了,没把程序结构处理好,看上去乱糟糟的。欢迎大家找茬。

加减乘除全部采用搬运字符的方法实现,即'1' + '2' 得'3',不是转换成数字后计算,用基本的C代码,不依赖任何库,gcc和g++都可以编译(测试部分除外)。

贴上全部函数的完整代码:


#include <stdio.h>

int dec_char_add(char in_carry, char c1, char c2, char * out_carry, char * result);
/*        dec_char_add() return 1 if no error, otherwise 0
*
*                                                c1                        ['0'-'9']                                        '6'
*                +                                c2                        ['0'-'9']                        +                '8'       
*                +                                in_carry        ['0'-'1']                        +                '1'
*        _________________________________________                ________________
*                =        out_carry        result                                                        =        '1'        '5'
*                        ['0'-'1']        ['0'-'9']
*/

int dec_char_sub(char in_borrow, char c1, char c2, char * out_borrow, char * result);
/*        dec_char_sub() return 1 if no error, otherwise 0
*
*                        ['0'-'1']
*                        out_borrow        c1                        ['0'-'9']                                '1'        '6'                                '0'        '6'       
*                -                                c2                        ['0'-'9']                        -                '8'                        -                '2'       
*                -                                in_borrow        ['0'-'1']                        -                '1'                        -                '1'       
*        _________________________________________                ________________        ________________
*                =                                result                                                        =                '7'                        =                '3'               
*                                                ['0'-'9']
*/

int is_dec_str(char * str, int * p_or_n, int * i_qty, int * d_qty, int * dot_pos);
/*        is_dec_str() return 1 if Yes, otherwise 0
*        Check str if a valid decimal number or not. Return 1 if Yes, or 0 if No.
*        str: the string to be checked.
*        p_or_n: indicate the number is positive (1) or negative (-1) (after check).
*        i_qty: integeral part char qty (length)
*        d_qty: decimal part char qty (length)
*        dot_pos: return position of '.', (or '\0' if no '.'), of the str
*        eg: if p_or_n = -1, i_qty = 5, d_qty = 2, dot_pos = 6 str may look like -nnnnn.nn
*/

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 sub_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);
/*sub_ip_dp() return 1 if no error, -1 if sub error (str1 < str2), 0 if other errors.
*sub 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 dec_str_add(char * str1, char * str2, char * str3, int str3_array_size, int * offset);
/*        dec_str_add() return 1 if no error, otherwise 0
*add decimal strings (str3 = str1 + str2)
*        str3: array to store result
*        str3_array_size: array size
*        offset: result will start from here (this function write result from tail to head)
*        better to have big size for str3,
*        at least +2 more than total length of str1 and str2 is suggested.
*/

int dec_str_sub(char * str1, char * str2, char * str3, int str3_array_size, int * offset);
/*        dec_str_sub() return 1 if no error, otherwise 0
*sub decimal strings (str3 = str1 - str2)
*        str3: array to store result
*        str3_array_size: array size
*        offset: result will start from here (this function write result from tail to head)
*        better to have big size for str3,
*        at least +2 more than total length of str1 and str2 is suggested.
*/

int add_up_str(char * s1, int * h, int * t, char * s2, int ls2, int s);
/*add_up_str() return 1 if no error, otherwise 0
*str1 += str2
*                  ****************369258147'\0'
*                  ^               ^       ^
*                  s1            h       t         h = head, t = tail
*                                          |
*             +               456789'\0' |         ls2 = length of s2
*                               ^    |   |               ('\0' not counted)
*                               s2   |   |
*                                    |<----|
*                                       s            s = shift to left (negative value)
*            ________________________________________
*                                                   
*             =    *************457158258147'\0'
*                  ^            ^          ^
*                  s1         h          t
*      
*/

int sub_off_str(char * s1, int * h, int * t, char * s2, int ls2, int s);
/*sub_off_str() return 1 if no error, -1 if sub error (str1 < str2), 0 if other errors.
*str1 -= str2
*                  *************457158258147'\0'
*                  ^            ^          ^
*                  s1         h          t         h = head, t = tail
*                                          |                                    
*             -               456789'\0' |         ls2 = length of s2
*                               ^    |   |               ('\0' not counted)
*                               s2   |   |
*                                    |<----|
*                                       s            s = shift to left (negative value)
*            ________________________________________
*                                                   
*             =    ****************369258147'\0'
*                  ^               ^       ^
*                  s1            h       t
*/

int sub_off_str_chk(char * s1, int * h, int * t, char * s2, int ls2, int s);
/*sub_off_str_chk() is almost same as sub_off_str()
*it will try to calulate and check if "borrow" happen (s1 < s2)
*keeps no change of s1, and also h and t.
*/

int dec_str_mul(char * str1, char * str2, char * str3, int str3_array_size, int * offset);
/*        dec_str_mul() return 1 if no error, otherwise 0
*mul decimal strings (str3 = str1 * str2)
*        str3: array to store result
*        str3_array_size: array size
*        offset: result will start from here (this function write result from tail to head)
*        better to have big size for str3,
*        at least (+2 more than total length of str1 and str2) * 2 is suggested.
*/

int dec_str_div(char * str1, char * str2, char * str3,
                        int str3_array_size, int max_decimal_len, int * offset);
/*        dec_str_mul() return 1 if no error, otherwise 0
*        div decimal strings (str3 = str1 / str2)
*str3: array to store result
*str3_array_size: array size
*max_decimal_len: the max length of decimal parts should kept
*                   eg: 20 keep 20 decimal parts
*                   eg: 0 keep no decimal parts
*                   eg: -1 calculate unitl the end of str3_array_size.
*        offset: result will start from here
*        better to have big size for str3,
*        at least (+2 more than total length of str1 and str2) * 4 is suggested.
*/

int main(void) //testing
{
        const int ArrSize = 1024; //accept length of chars during test.
        char str1;
        char str2;
        char str3;
        int index, r;
        printf("Enter 1st number: ");
        fgets(str1, ArrSize, stdin);
        for (int i = 0; i < ArrSize; i++)
        {
                if (str1 == '\n')
                {
                        str1 = '\0';
                        break;
                }
        }
        printf("Enter 2nd number: ");
        fgets(str2, ArrSize, stdin);
        for (int i = 0; i < ArrSize; i++)
        {
                if (str2 == '\n')
                {
                        str2 = '\0';
                        break;
                }
        }
        r = dec_str_add(str1, str2, str3, ArrSize * 4, &index);
        printf("return from dec_str_add() is %d\n", r);
        printf("   %s + %s \n = %s\n", str1, str2, str3 + index);
        r = dec_str_sub(str1, str2, str3, ArrSize * 4, &index);
        printf("return from dec_str_sub() is %d\n", r);
        printf("   %s - %s \n = %s\n", str1, str2, str3 + index);
        r = dec_str_mul(str1, str2, str3, ArrSize * 4, &index);
        printf("return from dec_str_mul() is %d\n", r);
        printf("   %s * %s \n = %s\n", str1, str2, str3 + index);
        r = dec_str_div(str1, str2, str3, ArrSize * 4, -1, &index);
        printf("return from dec_str_div() is %d\n", r);
        printf("   %s / %s \n = %s\n", str1, str2, str3 + index);
        return 0;
}

int dec_str_div(char * str1, char * str2, char * str3,
                        int str3_array_size, int max_decimal_len, int * offset)
{
        int pn1, pn2; //indicate positive or negative for str1 and str2.
        int iq1, iq2; //store integral part quantity for str1 and str2.
        int dq1, dq2; //store decimal part quantity for str1 and str2.
        int dp1, dp2; //store '.' position for str1 and str2.
        int rt1, rt2, rt3; //temp return value;
        int i, j;          //i and j are temp index
        int q;                  //q is a temp quantity
        char * s1;    //s1 is a copy of str1 without '.'
        char * s2;    //s2 is a copy of str2 without '.'
        int l1, l2;          //l1 and l2 is length of s1 and s2 ('\0' not counted).
        int h1, t1;          //h1 and t1 are both index to head and tail of valid chars in s1
        char * s3;          //s3 = s1 / s2
        int s3_array_size; //s3 array size
        int sft;           //sft is shift
        int h, t;          //h and t are both index to head and tail of valid chars in s3
        int d;                  //d is a index to dot position in s3
        int w;                  //w is a position to write in s3
        char ch;          //ch is a temp char
        char carry;   //carry is a temp carry
        char result_ch; //result_ch is a temp result char
        int moved_remainder_tail; //this index is same value as l2, otherwise wrong
        rt1 = is_dec_str(str1, &pn1, &iq1, &dq1, &dp1);
        if (rt1 == 0)
                return 0; //Error: str1 is not a number.
        rt2 = is_dec_str(str2, &pn2, &iq2, &dq2, &dp2);
        if (rt2 == 0)
                return 0; //Error: str2 is not a number.
        //divisor should not be zero, check if str2 is zero or not
        if (iq2 + dq2 == 1)
        {
                if (iq2 == 1 && str2 == '0')
                        return 0; //Error: str2 is "0"
                if (dq2 == 1 && str2 == '0')
                        return 0; //Error: str2 is ".0"
        }
        //copy valid chars of str1 to store in the begining of str3 (without '.')
        s1 = str3;
        i = iq1;
        j = 0;
        while (i > 0)
                s1 = str1; //copy integral parts
        i = 1;
        while (i <= dq1)
                s1 = str1; //copy decimal parts
        s1 = '\0';                                   //add '\0' in the end of string.
        l1 = j;                                                   //l1 = strlen(s1)
        //add '0' at tail of s1 if needed (s1 and s2 are both enlarged until no '.')
        if (dq1 < dq2)
        {
                q = dq2 - dq1;
                for (i = 0; i < q; i++)
                        s1 = '0';
                s1 = '\0';
        }
        //remove beginning '0' in s1, recalculate l1
        if (s1 == '0' && l1 > 1)
        {
                i = 0;
                j = 0;
                while (s1 == '0')
                        i++;                                   //i is an index first char of not '0'
                if (s1 == '\0')
                {                                                   //looks like "0000000"
                        s1 = '\0';
                        l1 = 1;
                }
                else
                {                        //looks like "0000066"
                        while (s1 != '\0')
                                s1 = s1;
                        s1 = '\0';
                        l1 = j;
                }
        }
        //copy valid chars of str2 to store in str3 (after s1) (without '.')
        s2 = s1 + (l1 + 1);
        i = iq2;
        j = 0;
        while (i > 0)
                s2 = str2; //copy integral parts
        i = 1;
        while (i <= dq2)
                s2 = str2; //copy decimal parts
        s2 = '\0';                                   //add '\0' in the end of string.
        l2 = j;                                                   //l2 = strlen(s2)
        //add '0' at tail of s2 if needed (s1 and s2 are both enlarged until no '.')
        if (dq2 < dq1)
        {
                q = dq1 - dq2;
                for (i = 0; i < q; i++)
                        s2 = '0';
                s2 = '\0';
        }
        //remove beginning '0' in s2, recalculate l2
        if (s2 == '0' && l2 > 1)
        {
                i = 0;
                j = 0;
                while (s2 == '0')
                        i++;                                   //i is an index first char of not '0'
                if (s2 == '\0')
                {                                                   //looks like "0000000"
                        s2 = '\0';
                        l2 = 1;
                }
                else
                {                        //looks like "0000066"
                        while (s2 != '\0')
                                s2 = s2;
                        s2 = '\0';
                        l2 = j;
                }
        }
        //enlarge space for s1, need more space to be a dividend
        h1 = 0;                                        //head of s1 before enlarge
        t1 = l1 - 1;                        //tail of s1 before enlarge
        q = (str3_array_size - (l2 + 1)) / 2; //expected size
        if (q < (l1 + 1))
                return 0;                        //Error: no enough space in str3
        q = q - (l1 + 1);                //quantity of space to move backward
        i = l1 + 1 + l2 + 1;        //current index of s2 end
        j = i + q;                                //new index of s2 end
        while (i >= 0)
                str3 = str3; //move backward for s1 and s2.
        h1 += q;
        t1 += q;
        l1 += q;
        s2 += q;
        //divide s1 by s2, store result in s3 (after s2), step 1, initial s3.
        s3 = s2 + (l2 + 1);
        s3_array_size = str3_array_size - (l1 + 1) - (l2 + 1);
        d = -1; //dot position set an inpossible value.
        //divide s1 by s2, store result in s3 (after s2), step 2, calc integeral parts.
        i = t1 - h1 + 1 - l2; //i is a shift now (length of s1 - length of s2)
        w = 1; //write result to: start from s3, leave s3 for negative simbol if need
        h = w;
        if (i < 0)
        {
                s3 = '0';
                t = w;
                w++;
        }
        for (    ; i >= 0; --i)
        {
                if (h1 == t1 && h1 == '0')
                        s3 = '0';        //remainder is '0', directly fill '0' instead calculate.
                else
                {
                        ch = '0';
                        carry = '0';
                        while (-1 != sub_off_str_chk(s1, &h1, &t1, s2, l2, -i))
                        {
                                rt3 = sub_off_str(s1, &h1, &t1, s2, l2, -i);
                                if (rt3 == 0)
                                        return 0; //Error: something wrong.
                                rt3 = dec_char_add(carry, ch, '1', &carry, &result_ch); //ch++
                                if (rt3 == 0)
                                        return 0; //Error: something wrong.
                                ch = result_ch;
                                if (carry == '1')
                                        return 0; //Error: something wrong.
                                if (ch == '9')
                                        break;    //finish: successfully looped 9 times, don't loop more
                        }
                        s3 = ch;
                }
                t = w;
                w++;
        }
        if (h1 == t1 && s1 == '0')        //if no remainders.
                max_decimal_len = 0;                //set it to 0 will skip step 3 to 5
        //divide s1 by s2, store result in s3 (after s2), step 3, put a '.' in s3.
        if (max_decimal_len != 0)
        {
                d = w;                        //record dot position of s3
                s3 = '.';
                t = w;
                w++;
        }
        //divide s1 by s2, store result in s3 (after s2), step 4, move s1 remainders to front.
        if (max_decimal_len != 0)
        {
                moved_remainder_tail = (l2 > (t1 - h1 + 1)) ? l2 : (t1 - h1 + 1);
                i = t1;
                j = moved_remainder_tail;
                while (i >= h1)                                //moving s1
                        s1 = s1;
                h1 = ++j;                                        //note: h1 is certainly >= 1
                for (i = moved_remainder_tail + 1; i <= t1; i++)
                        s1 = '0';                        //fill '0' following s1 remainders
        }
        //divide s1 by s2, store result in s3 (after s2), step 5, calc decimal parts.
        if (max_decimal_len != 0)
        {
                i = t1 - (moved_remainder_tail + 1); //i is a shift, + 1 means first decimal part
                if (i < 0) //impossible
                {
                        s3 = '0';
                        t = w;
                        w++;
                }
                for (    ; i >= 0; --i)
                {
                        if (h1 == t1 && h1 == '0')
                                break;        //stop now, remainder is '0', no need continue for decimal parts.
                        ch = '0';
                        carry = '0';
                        while (-1 != sub_off_str_chk(s1, &h1, &t1, s2, l2, -i))
                        {
                                rt3 = sub_off_str(s1, &h1, &t1, s2, l2, -i);
                                if (rt3 == 0)
                                        return 0; //Error: something wrong.
                                rt3 = dec_char_add(carry, ch, '1', &carry, &result_ch); //ch++
                                if (rt3 == 0)
                                        return 0; //Error: something wrong.
                                ch = result_ch;
                                if (carry == '1')
                                        return 0; //Error: something wrong.
                                if (ch == '9')
                                        break;    //finish: successfully looped 9 times, don't loop more
                        }
                        s3 = ch;
                        t = w;
                        w++;
                        if (w == s3_array_size - 1)
                                break; //one char space left. finish now.(last space for '\0')
                        if (w > s3_array_size - 1)
                                break; //impossible
                        if (max_decimal_len != -1)
                        {
                                if (t - d == max_decimal_len)
                                        break; //finish now
                                if (t - d > max_decimal_len)
                                        break; //impossible
                        }
                }
        }
        //divide s1 by s2, store result in s3 (after s2), step 5, remove excessive '0' in s3.
        if (d == -1)        //s3 is an integer, dot position had not been set
                d = t + 1;        //set it at the end of s3 string.
        while (s3 == '0' && d - h > 1) //remove '0' at front of integeral parts
                h++;
        while (s3 == '0' && t - d > 0) //remove '0' at end of decimal parts
                t--;
        if (s3 == '.') //all decimal parts are '0' and have been removed
                t--;
        //divide s1 by s2, store result in s3 (after s2), step 6, write '\0' in the end of s3.
        s3 = '\0';
        //insert '-' for s3 if applicable
        if (pn1 * pn2 == -1)
        {
                if (s3 == '0' && s3 == '\0')
                        ; //it's 0, do nothing
                else
                {
                        i = h;
                        if (--i < 0)
                                return 0; //Error: no enough space in s3
                        s3 = '-';
                        h = i;
                }
        }       
        //caculate result offset for str3.
        *offset = h + (l1 + 1) + (l2 + 1);
        return 1;
}

int dec_str_mul(char * str1, char * str2, char * str3, int str3_array_size, int * offset)
{
        int pn1, pn2; //indicate positive or negative for str1 and str2.
        int iq1, iq2; //store integral part quantity for str1 and str2.
        int dq1, dq2; //store decimal part quantity for str1 and str2.
        int dp1, dp2; //store '.' position for str1 and str2.
        int rt1, rt2, rt3; //temp return value;
        int i, j;          //i and j are temp index
        char * s1;    //s1 is a copy of str1 without '.'
        char * s2;    //s2 is a copy of str2 without '.'
        int l1, l2;          //l1 and l2 is length of s1 and s2 ('\0' not counted).
        char * s3;          //s3 = s1 * s2
        int s3_array_size; //s3 array size
        int h, t;          //h and t are both index to head and tail of valid chars in s3
        char ch;          //ch is a temp char
        char carry;          //carry is a temp carry
        char result_ch; //result_ch is a temp result char
        rt1 = is_dec_str(str1, &pn1, &iq1, &dq1, &dp1);
        if (rt1 == 0)
                return 0; //Error: str1 is not a number.
        rt2 = is_dec_str(str2, &pn2, &iq2, &dq2, &dp2);
        if (rt2 == 0)
                return 0; //Error: str2 is not a number.
        //copy valid chars of str1 to store in the begining of str3 (without '.')
        s1 = str3;
        i = iq1;
        j = 0;
        while (i > 0)
                s1 = str1; //copy integral parts
        i = 1;
        while (i <= dq1)
                s1 = str1; //copy decimal parts
        s1 = '\0';                                   //add '\0' in the end of string.
        l1 = j;                                                   //l1 = strlen(s1)
        //remove beginning '0' in s1, recalculate l1
        if (s1 == '0' && l1 > 1)
        {
                i = 0;
                j = 0;
                while (s1 == '0')
                        i++;                                   //i is an index first char of not '0'
                if (s1 == '\0')
                {                                                   //looks like "0000000"
                        s1 = '\0';
                        l1 = 1;
                }
                else
                {                        //looks like "0000066"
                        while (s1 != '\0')
                                s1 = s1;
                        s1 = '\0';
                        l1 = j;
                }
        }
        //copy valid chars of str2 to store in str3 (after s1) (without '.')
        s2 = s1 + (l1 + 1);
        i = iq2;
        j = 0;
        while (i > 0)
                s2 = str2; //copy integral parts
        i = 1;
        while (i <= dq2)
                s2 = str2; //copy decimal parts
        s2 = '\0';                                   //add '\0' in the end of string.
        l2 = j;                                                   //l2 = strlen(s2)
        //remove beginning '0' in s2, recalculate l2
        if (s2 == '0' && l2 > 1)
        {
                i = 0;
                j = 0;
                while (s2 == '0')
                        i++;                                   //i is an index first char of not '0'
                if (s2 == '\0')
                {                                                   //looks like "0000000"
                        s2 = '\0';
                        l2 = 1;
                }
                else
                {                        //looks like "0000066"
                        while (s2 != '\0')
                                s2 = s2;
                        s2 = '\0';
                        l2 = j;
                }
        }
        //multiply s1 and s2, store result in s3 (after s2)
        s3 = s2 + (l2 + 1);
        s3_array_size = str3_array_size - (l1 + 1) - (l2 + 1);
        t = s3_array_size - 1;//t now point to the last item of array.
        s3 = '\0';                        //notice: leave 2 '\0' at the end of s3.
        s3 = '\0';                       
        s3 = '0';                        //s3 initialed as value of '0'
        h = t;
        for (i = 0; i < l2; i++) //loop every char of s2
        {
                j = l2 - 1 - i;               //index of s2 (from tail to head)
                ch = '0';                       //ch is a temp char
                carry = '0';               //carry is a temp carry
                while (s2 != ch)
                {
                        rt3 = add_up_str(s3, &h, &t, s1, l1, -i); //s1 * s2
                        if (rt3 == 0)
                                return 0; //Error: something wrong.
                        rt3 = dec_char_add(carry, ch, '1', &carry, &result_ch); //ch++
                        if (rt3 == 0)
                                return 0; //Error: something wrong.
                        ch = result_ch;
                        if (carry == '1')
                                return 0; //Error: something wrong.
                }
        }
        //insert '.' for s3 if applicable
        if (dq1 + dq2 != 0)
        {
                i = dq1 + dq2;
                j = t;
                while (i > 0)
                {
                        s3 = s3; //don't worry, remember, s3 has 2 '\0' in the end.
                        j--;
                        i--;
                        if (j < h) //oh, you should fill '0' in the front
                        {
                                if (--h < 0)
                                        return 0; //Error: no enough space in s3
                                s3 = '0';
                        }
                }
                s3 = '.';
                t++;
        }
        //remove ending '0' in the decimal part of s3
        if (dq1 + dq2 != 0)
        {
                while (s3 == '0')
                        s3 = '\0';
        }
        //remove ending '.' if s3 end with '.'
        if (s3 == '.')
                s3 = '\0';
        //remove excessive '0' in the front of integeral parts
        while (s3 == '0')
                h++;
        if (s3 == '\0' || s3 == '.')
        {
                if (--h < 0)
                        return 0; //Error: no enough space in s3
                s3 = '0';
        }
        //insert '-' for s3 if applicable
        if (pn1 * pn2 == -1)
        {
                if (s3 == '0' && s3 == '\0')
                        ; //it's 0, do nothing
                else
                {
                        i = h;
                        if (--i < 0)
                                return 0; //Error: no enough space in s3
                        s3 = '-';
                        h = i;
                }
        }
        //caculate result offset for str3.
        *offset = h + (l1 + 1) + (l2 + 1);
        return 1;
}

int sub_off_str_chk(char * s1, int * h, int * t, char * s2, int ls2, int s)
{
        int yh = *h;         // yh = copy of *h
        int yt = *t;         // yt = copy of *t
        int i1 = yt + s;       // i1 is char index of s1
        int i2 = ls2 - 1;      // i2 is char index of s2
        char borrow = '0';   // borrow is a borrow
        char c1, c2, c3;       // c1, c2 and c3 are temp chars
        while (i2 >= 0)      // loop from the tail char to the head char of s2
        {
                if (i1 < 0)      // Error: not enough space in s1
                        return 0;
                while (i1 < yh)    // fill '0' before s1 if necessary
                {
                        --(yh);
                        if (yh < 0)    // Error: not enough space in s1
                                return 0;
                        s1 = '0';
                }
                c1 = s1;
                c2 = s2;
                if (0 == dec_char_sub(borrow, c1, c2, &borrow, &c3))
                        return 0;      // Error: return error from dec_char_sub()
                // s1 = c3;    // no write back, check only.
                --i1;
                --i2;
        }
        while (borrow == '1')// continue with i1: loop until borrow =='0'
        {
                if (i1 < 0)      // Error: not enough space in s1
                        return 0;
                if (i1 < yh)       // Error: s1 < s2
                        return -1;
                c1 = s1;
                c2 = '0';
                if (0 == dec_char_sub(borrow, c1, c2, &borrow, &c3))
                        return 0;      // Error: return error from dec_char_sub()
                // s1 = c3;    // no write back, check only.
                --i1;
        }
        while (s1 == '0' && yh < yt)// ignore beginning '0' in s1
                ++(yh);
        return 1;
}

int sub_off_str(char * s1, int * h, int * t, char * s2, int ls2, int s)
{
        int i1 = *t + s;       // i1 is char index of s1
        int i2 = ls2 - 1;      // i2 is char index of s2
        char borrow = '0';   // borrow is a borrow
        char c1, c2, c3;       // c1, c2 and c3 are temp chars
        while (i2 >= 0)      // loop from the tail char to the head char of s2
        {
                if (i1 < 0)      // Error: not enough space in s1
                        return 0;
                while (i1 < *h)    // fill '0' before s1 if necessary
                {
                        --(*h);
                        if (*h < 0)    // Error: not enough space in s1
                                return 0;
                        s1[*h] = '0';
                }
                c1 = s1;
                c2 = s2;
                if (0 == dec_char_sub(borrow, c1, c2, &borrow, &c3))
                        return 0;      // Error: return error from dec_char_sub()
                s1 = c3;
                --i1;
                --i2;
        }
        while (borrow == '1')// continue with i1: loop until borrow =='0'
        {
                if (i1 < 0)      // Error: not enough space in s1
                        return 0;
                if (i1 < *h)       // Error: s1 < s2
                        return -1;
                c1 = s1;
                c2 = '0';
                if (0 == dec_char_sub(borrow, c1, c2, &borrow, &c3))
                        return 0;      // Error: return error from dec_char_sub()
                s1 = c3;
                --i1;
        }
        while (s1[*h] == '0' && *h < *t)// ignore beginning '0' in s1
                ++(*h);
        return 1;
}

int add_up_str(char * s1, int * h, int * t, char * s2, int ls2, int s)
{
        int i1 = *t + s;       // i1 is char index of s1
        int i2 = ls2 - 1;      // i2 is char index of s2
        char carry = '0';      // carry is a carry
        char c1, c2, c3;       // c1, c2 and c3 are temp chars
        while (i2 >= 0)      // loop from the tail char to the head char of s2
        {
                if (i1 < 0)      // Error: not enough space in s1
                        return 0;
                while (i1 < *h)    // fill '0' before s1 if necessary
                {
                        --(*h);
                        if (*h < 0)    // Error: not enough space in s1
                                return 0;
                        s1[*h] = '0';
                }
                c1 = s1;
                c2 = s2;
                if (0 == dec_char_add(carry, c1, c2, &carry, &c3))
                        return 0;      // Error: return error from dec_char_add()
                s1 = c3;
                --i1;
                --i2;
        }
        while (carry == '1')   // continue with i1: loop until carry =='0'
        {
                if (i1 < 0)      // Error: not enough space in s1
                        return 0;
                while (i1 < *h)    // fill '0' before s1 if necessary
                {
                        --(*h);
                        if (*h < 0)    // Error: not enough space in s1
                                return 0;
                        s1[*h] = '0';
                }
                c1 = s1;
                c2 = '0';
                if (0 == dec_char_add(carry, c1, c2, &carry, &c3))
                        return 0;      // Error: return error from dec_char_add()
                s1 = c3;
                --i1;
        }
        return 1;
}

int dec_str_sub(char * str1, char * str2, char * str3, int str3_array_size, int * offset)
{
        int pn1, pn2; //indicate positive or negative for str1 and str2.
        int iq1, iq2; //store integral part quantity for str1 and str2.
        int dq1, dq2; //store decimal part quantity for str1 and str2.
        int dp1, dp2; //store '.' position for str1 and str2.
        int rt1, rt2, rt3; //temp return value;
        rt1 = is_dec_str(str1, &pn1, &iq1, &dq1, &dp1);
        if (rt1 == 0)
                return 0; //Error: str1 is not a number.
        rt2 = is_dec_str(str2, &pn2, &iq2, &dq2, &dp2);
        if (rt2 == 0)
                return 0; //Error: str2 is not a number.
        if (pn1 == 1 && pn2 == -1)                        //str1 is positive, str2 is negative
        {
                rt3 = add_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
        }
        else if (pn1 == 1 && pn2 == 1)                //str1 is positive, str2 is positive
        {
                rt3 = sub_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
                if (rt3 == -1)
                {        //switch str1 and str2, try again.
                        rt3 = sub_ip_dp(str2, dp2, iq2, dq2, str1, dp1, iq1, dq1,
                                                        str3, str3_array_size, offset);
                        if (rt3 == 0)
                                return 0; //Error: failed again finally.
                        if (--(*offset) >= 0)
                                str3[*offset] = '-'; //put on a '-' for str3
                        else
                                return 0; //Error: not enough space in str3
                }
        }
        else if (pn1 == -1 && pn2 == -1)                //str1 is negative, str2 is negative
        {
                rt3 = sub_ip_dp(str2, dp2, iq2, dq2, str1, dp1, iq1, dq1,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
                if (rt3 == -1)
                {        //switch str1 and str2, try again.
                        rt3 = sub_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                        str3, str3_array_size, offset);
                        if (rt3 == 0)
                                return 0; //Error: failed again finally.
                        if (--(*offset) >= 0)
                                str3[*offset] = '-'; //put on a '-' for str3
                        else
                                return 0; //Error: not enough space in str3
                }
        }
        else if (pn1 == -1 && pn2 == 1)        //str1 is negative, str2 is positive
        {
                rt3 = add_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
                if (str3[*offset] == '0' && str3[*offset+1]        == '\0')
                        ;                //do nothing, it's 0, don't put on '-', happened while (-0) - (0)
                else
                {
                        if (--(*offset) >= 0)
                                str3[*offset] = '-'; //put on a '-' for str3
                        else
                                return 0; //Error: not enough space in str3
                }
        }
        else
                return 0; //Error: something wrong, not possible.
        return 1; //Done.
}

int dec_str_add(char * str1, char * str2, char * str3, int str3_array_size, int * offset)
{
        int pn1, pn2; //indicate positive or negative for str1 and str2.
        int iq1, iq2; //store integral part quantity for str1 and str2.
        int dq1, dq2; //store decimal part quantity for str1 and str2.
        int dp1, dp2; //store '.' position for str1 and str2.
        int rt1, rt2, rt3; //temp return value;
        rt1 = is_dec_str(str1, &pn1, &iq1, &dq1, &dp1);
        if (rt1 == 0)
                return 0; //Error: str1 is not a number.
        rt2 = is_dec_str(str2, &pn2, &iq2, &dq2, &dp2);
        if (rt2 == 0)
                return 0; //Error: str2 is not a number.
        if (pn1 == 1 && pn2 == 1)                        //str1 is positive, str2 is positive
        {
                rt3 = add_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
        }
        else if (pn1 == 1 && pn2 == -1)                //str1 is positive, str2 is negative
        {
                rt3 = sub_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
                if (rt3 == -1)
                {        //switch str1 and str2, try again.
                        rt3 = sub_ip_dp(str2, dp2, iq2, dq2, str1, dp1, iq1, dq1,
                                                        str3, str3_array_size, offset);
                        if (rt3 == 0)
                                return 0; //Error: failed again finally.
                        if (--(*offset) >= 0)
                                str3[*offset] = '-'; //put on a '-' for str3
                        else
                                return 0; //Error: not enough space in str3
                }
        }
        else if (pn1 == -1 && pn2 == 1)                //str1 is negative, str2 is positive
        {
                rt3 = sub_ip_dp(str2, dp2, iq2, dq2, str1, dp1, iq1, dq1,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
                if (rt3 == -1)
                {        //switch str1 and str2, try again.
                        rt3 = sub_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                        str3, str3_array_size, offset);
                        if (rt3 == 0)
                                return 0; //Error: failed again finally.
                        if (--(*offset) >= 0)
                                str3[*offset] = '-'; //put on a '-' for str3
                        else
                                return 0; //Error: not enough space in str3
                }
        }
        else if (pn1 == -1 && pn2 == -1)        //str1 is negative, str2 is negative
        {
                rt3 = add_ip_dp(str1, dp1, iq1, dq1, str2, dp2, iq2, dq2,
                                                str3, str3_array_size, offset);
                if (rt3 == 0)
                        return 0; //Error: failed, maybe, not enough space in str3
                if (str3[*offset] == '0' && str3[*offset+1]        == '\0')
                        ;        //do nothing, it's 0, don't put on '-', happened while (-0) + (-0)
                else
                {
                        if (--(*offset) >= 0)
                                str3[*offset] = '-'; //put on a '-' for str3
                        else
                                return 0; //Error: not enough space in str3
                }
        }
        else
                return 0; //Error: something wrong, not possible.
        return 1; //Done.
}

int sub_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 if no error, -1 if sub error (str1 < str2), 0 if other errors.
        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 borrow = '0';                                // borrow is a borrow
        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

        // sub 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_sub(borrow, c1, c2, &borrow, &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
        }

        // sub 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_sub(borrow, c1, c2, &borrow, &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 borrow after last dec_char_sub()
        if (borrow == '1')
                return -1;                //Error: str1 is smaller than str2, it's not allowed
                                                //you should switch str1 and str2
                                                //try again: - (str2 - str1)

        // 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
}

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
}

int is_dec_str(char * str, int * p_or_n, int * i_qty, int * d_qty, int * dot_pos)
{
        int ret_val = 1; //return value, 1 = Yes, 0 = No.
        int dot_qty = 0; //'.' qty found in the str
        int i = 0;               //i is an index of str.
        switch (str)
        {
                case '-': *p_or_n = -1; i++; break;        //negative number and bypass the '-'
                case '+': i++;                                                //bypass the '+'
                default: *p_or_n = 1;                                //positive number
        }
        *i_qty = 0;
        *d_qty = 0;
        *dot_pos = -1;        //initialized as a not possible value.
        while (ret_val == 1 && str != '\0')
        {
                switch (str)
                {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':        dot_qty ? ++(*d_qty) : ++(*i_qty);
                                                break;
                        case '.':        if (++dot_qty > 1)
                                                        ret_val = 0;        //Error: too many '.'
                                                *dot_pos = i;
                                                break;
                        default: ret_val = 0;        //Error: unexpected char found
                }
                i++;
        }
        if (*i_qty == 0 && *d_qty == 0)       
                ret_val = 0;                //Error: no valid number found
        if (ret_val == 1)
        {
                if (*dot_pos == -1)        //there is no '.' in the str, str is an integer
                        *dot_pos = i;        //dot_pos set at '\0'(str end) for "no dot" integer
                if (*i_qty > 0)
                        while (*d_qty > 0 && str[*dot_pos + *d_qty] == '0')
                                --(*d_qty);        //ignore excessive '0' in the end of decimal part
                else
                        while (*d_qty > 1 && str[*dot_pos + *d_qty] == '0')
                                --(*d_qty);        //ignore excessive '0' in the end of decimal part(leave 1)
                if (*d_qty > 0)
                        while (*i_qty > 0 && str[*dot_pos - *i_qty] == '0')
                                --(*i_qty);        //ignore excessive '0' in the begining of integeral part
                else
                        while (*i_qty > 1 && str[*dot_pos - *i_qty] == '0')
                                --(*i_qty);        //ignore excessive '0' in the begining of integeral part(leave 1)
        }
        else
        {
                *p_or_n = 0;
                *i_qty = 0;
                *d_qty = 0;
                *dot_pos = 0;
        }
        return ret_val;
}

int dec_char_sub(char in_borrow, char c1, char c2, char * out_borrow, char * result)
{
        int ret_val = 1; //return value, 1 = no error, otherwise 0
        switch (c1)                //go through "switch case" to get answer without calculate.
        {
                case '0':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '0'; break;
                                                case '1': *out_borrow = '1'; *result = '9'; break;
                                                case '2': *out_borrow = '1'; *result = '8'; break;
                                                case '3': *out_borrow = '1'; *result = '7'; break;
                                                case '4': *out_borrow = '1'; *result = '6'; break;
                                                case '5': *out_borrow = '1'; *result = '5'; break;
                                                case '6': *out_borrow = '1'; *result = '4'; break;
                                                case '7': *out_borrow = '1'; *result = '3'; break;
                                                case '8': *out_borrow = '1'; *result = '2'; break;
                                                case '9': *out_borrow = '1'; *result = '1'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '1':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '1'; break;
                                                case '1': *out_borrow = '0'; *result = '0'; break;
                                                case '2': *out_borrow = '1'; *result = '9'; break;
                                                case '3': *out_borrow = '1'; *result = '8'; break;
                                                case '4': *out_borrow = '1'; *result = '7'; break;
                                                case '5': *out_borrow = '1'; *result = '6'; break;
                                                case '6': *out_borrow = '1'; *result = '5'; break;
                                                case '7': *out_borrow = '1'; *result = '4'; break;
                                                case '8': *out_borrow = '1'; *result = '3'; break;
                                                case '9': *out_borrow = '1'; *result = '2'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '2':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '2'; break;
                                                case '1': *out_borrow = '0'; *result = '1'; break;
                                                case '2': *out_borrow = '0'; *result = '0'; break;
                                                case '3': *out_borrow = '1'; *result = '9'; break;
                                                case '4': *out_borrow = '1'; *result = '8'; break;
                                                case '5': *out_borrow = '1'; *result = '7'; break;
                                                case '6': *out_borrow = '1'; *result = '6'; break;
                                                case '7': *out_borrow = '1'; *result = '5'; break;
                                                case '8': *out_borrow = '1'; *result = '4'; break;
                                                case '9': *out_borrow = '1'; *result = '3'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '3':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '3'; break;
                                                case '1': *out_borrow = '0'; *result = '2'; break;
                                                case '2': *out_borrow = '0'; *result = '1'; break;
                                                case '3': *out_borrow = '0'; *result = '0'; break;
                                                case '4': *out_borrow = '1'; *result = '9'; break;
                                                case '5': *out_borrow = '1'; *result = '8'; break;
                                                case '6': *out_borrow = '1'; *result = '7'; break;
                                                case '7': *out_borrow = '1'; *result = '6'; break;
                                                case '8': *out_borrow = '1'; *result = '5'; break;
                                                case '9': *out_borrow = '1'; *result = '4'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '4':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '4'; break;
                                                case '1': *out_borrow = '0'; *result = '3'; break;
                                                case '2': *out_borrow = '0'; *result = '2'; break;
                                                case '3': *out_borrow = '0'; *result = '1'; break;
                                                case '4': *out_borrow = '0'; *result = '0'; break;
                                                case '5': *out_borrow = '1'; *result = '9'; break;
                                                case '6': *out_borrow = '1'; *result = '8'; break;
                                                case '7': *out_borrow = '1'; *result = '7'; break;
                                                case '8': *out_borrow = '1'; *result = '6'; break;
                                                case '9': *out_borrow = '1'; *result = '5'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '5':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '5'; break;
                                                case '1': *out_borrow = '0'; *result = '4'; break;
                                                case '2': *out_borrow = '0'; *result = '3'; break;
                                                case '3': *out_borrow = '0'; *result = '2'; break;
                                                case '4': *out_borrow = '0'; *result = '1'; break;
                                                case '5': *out_borrow = '0'; *result = '0'; break;
                                                case '6': *out_borrow = '1'; *result = '9'; break;
                                                case '7': *out_borrow = '1'; *result = '8'; break;
                                                case '8': *out_borrow = '1'; *result = '7'; break;
                                                case '9': *out_borrow = '1'; *result = '6'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '6':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '6'; break;
                                                case '1': *out_borrow = '0'; *result = '5'; break;
                                                case '2': *out_borrow = '0'; *result = '4'; break;
                                                case '3': *out_borrow = '0'; *result = '3'; break;
                                                case '4': *out_borrow = '0'; *result = '2'; break;
                                                case '5': *out_borrow = '0'; *result = '1'; break;
                                                case '6': *out_borrow = '0'; *result = '0'; break;
                                                case '7': *out_borrow = '1'; *result = '9'; break;
                                                case '8': *out_borrow = '1'; *result = '8'; break;
                                                case '9': *out_borrow = '1'; *result = '7'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '7':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '7'; break;
                                                case '1': *out_borrow = '0'; *result = '6'; break;
                                                case '2': *out_borrow = '0'; *result = '5'; break;
                                                case '3': *out_borrow = '0'; *result = '4'; break;
                                                case '4': *out_borrow = '0'; *result = '3'; break;
                                                case '5': *out_borrow = '0'; *result = '2'; break;
                                                case '6': *out_borrow = '0'; *result = '1'; break;
                                                case '7': *out_borrow = '0'; *result = '0'; break;
                                                case '8': *out_borrow = '1'; *result = '9'; break;
                                                case '9': *out_borrow = '1'; *result = '8'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '8':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '8'; break;
                                                case '1': *out_borrow = '0'; *result = '7'; break;
                                                case '2': *out_borrow = '0'; *result = '6'; break;
                                                case '3': *out_borrow = '0'; *result = '5'; break;
                                                case '4': *out_borrow = '0'; *result = '4'; break;
                                                case '5': *out_borrow = '0'; *result = '3'; break;
                                                case '6': *out_borrow = '0'; *result = '2'; break;
                                                case '7': *out_borrow = '0'; *result = '1'; break;
                                                case '8': *out_borrow = '0'; *result = '0'; break;
                                                case '9': *out_borrow = '1'; *result = '9'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '9':        switch (c2)
                                        {
                                                case '0': *out_borrow = '0'; *result = '9'; break;
                                                case '1': *out_borrow = '0'; *result = '8'; break;
                                                case '2': *out_borrow = '0'; *result = '7'; break;
                                                case '3': *out_borrow = '0'; *result = '6'; break;
                                                case '4': *out_borrow = '0'; *result = '5'; break;
                                                case '5': *out_borrow = '0'; *result = '4'; break;
                                                case '6': *out_borrow = '0'; *result = '3'; break;
                                                case '7': *out_borrow = '0'; *result = '2'; break;
                                                case '8': *out_borrow = '0'; *result = '1'; break;
                                                case '9': *out_borrow = '0'; *result = '0'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                default:        ret_val = 1; //Error: c1 out of range
        }
        switch (in_borrow)        //go through "switch case" to get answer without calculate.
        {
                case '0':        break;
                case '1':        switch (*result)
                                        {
                                                case '0': *out_borrow = '1'; *result = '9'; break;
                                                case '1': *result = '0'; break;
                                                case '2': *result = '1'; break;
                                                case '3': *result = '2'; break;
                                                case '4': *result = '3'; break;
                                                case '5': *result = '4'; break;
                                                case '6': *result = '5'; break;
                                                case '7': *result = '6'; break;
                                                case '8': *result = '7'; break;
                                                case '9': *result = '8'; break;
                                        }
                                        break;
                default:        ret_val = 0; //Error: in_carry out of range
        }
        if (ret_val != 1)
        {
                *out_borrow = '0';
                *result = '0';
        }
        return ret_val;
}

int dec_char_add(char in_carry, char c1, char c2, char * out_carry, char * result)
{
        int ret_val = 1; //return value, 1 = no error, otherwise 0
        switch (c1)                //go through "switch case" to get answer without calculate.
        {
                case '0':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '0'; break;
                                                case '1': *out_carry = '0'; *result = '1'; break;
                                                case '2': *out_carry = '0'; *result = '2'; break;
                                                case '3': *out_carry = '0'; *result = '3'; break;
                                                case '4': *out_carry = '0'; *result = '4'; break;
                                                case '5': *out_carry = '0'; *result = '5'; break;
                                                case '6': *out_carry = '0'; *result = '6'; break;
                                                case '7': *out_carry = '0'; *result = '7'; break;
                                                case '8': *out_carry = '0'; *result = '8'; break;
                                                case '9': *out_carry = '0'; *result = '9'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '1':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '1'; break;
                                                case '1': *out_carry = '0'; *result = '2'; break;
                                                case '2': *out_carry = '0'; *result = '3'; break;
                                                case '3': *out_carry = '0'; *result = '4'; break;
                                                case '4': *out_carry = '0'; *result = '5'; break;
                                                case '5': *out_carry = '0'; *result = '6'; break;
                                                case '6': *out_carry = '0'; *result = '7'; break;
                                                case '7': *out_carry = '0'; *result = '8'; break;
                                                case '8': *out_carry = '0'; *result = '9'; break;
                                                case '9': *out_carry = '1'; *result = '0'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '2':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '2'; break;
                                                case '1': *out_carry = '0'; *result = '3'; break;
                                                case '2': *out_carry = '0'; *result = '4'; break;
                                                case '3': *out_carry = '0'; *result = '5'; break;
                                                case '4': *out_carry = '0'; *result = '6'; break;
                                                case '5': *out_carry = '0'; *result = '7'; break;
                                                case '6': *out_carry = '0'; *result = '8'; break;
                                                case '7': *out_carry = '0'; *result = '9'; break;
                                                case '8': *out_carry = '1'; *result = '0'; break;
                                                case '9': *out_carry = '1'; *result = '1'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '3':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '3'; break;
                                                case '1': *out_carry = '0'; *result = '4'; break;
                                                case '2': *out_carry = '0'; *result = '5'; break;
                                                case '3': *out_carry = '0'; *result = '6'; break;
                                                case '4': *out_carry = '0'; *result = '7'; break;
                                                case '5': *out_carry = '0'; *result = '8'; break;
                                                case '6': *out_carry = '0'; *result = '9'; break;
                                                case '7': *out_carry = '1'; *result = '0'; break;
                                                case '8': *out_carry = '1'; *result = '1'; break;
                                                case '9': *out_carry = '1'; *result = '2'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '4':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '4'; break;
                                                case '1': *out_carry = '0'; *result = '5'; break;
                                                case '2': *out_carry = '0'; *result = '6'; break;
                                                case '3': *out_carry = '0'; *result = '7'; break;
                                                case '4': *out_carry = '0'; *result = '8'; break;
                                                case '5': *out_carry = '0'; *result = '9'; break;
                                                case '6': *out_carry = '1'; *result = '0'; break;
                                                case '7': *out_carry = '1'; *result = '1'; break;
                                                case '8': *out_carry = '1'; *result = '2'; break;
                                                case '9': *out_carry = '1'; *result = '3'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '5':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '5'; break;
                                                case '1': *out_carry = '0'; *result = '6'; break;
                                                case '2': *out_carry = '0'; *result = '7'; break;
                                                case '3': *out_carry = '0'; *result = '8'; break;
                                                case '4': *out_carry = '0'; *result = '9'; break;
                                                case '5': *out_carry = '1'; *result = '0'; break;
                                                case '6': *out_carry = '1'; *result = '1'; break;
                                                case '7': *out_carry = '1'; *result = '2'; break;
                                                case '8': *out_carry = '1'; *result = '3'; break;
                                                case '9': *out_carry = '1'; *result = '4'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '6':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '6'; break;
                                                case '1': *out_carry = '0'; *result = '7'; break;
                                                case '2': *out_carry = '0'; *result = '8'; break;
                                                case '3': *out_carry = '0'; *result = '9'; break;
                                                case '4': *out_carry = '1'; *result = '0'; break;
                                                case '5': *out_carry = '1'; *result = '1'; break;
                                                case '6': *out_carry = '1'; *result = '2'; break;
                                                case '7': *out_carry = '1'; *result = '3'; break;
                                                case '8': *out_carry = '1'; *result = '4'; break;
                                                case '9': *out_carry = '1'; *result = '5'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '7':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '7'; break;
                                                case '1': *out_carry = '0'; *result = '8'; break;
                                                case '2': *out_carry = '0'; *result = '9'; break;
                                                case '3': *out_carry = '1'; *result = '0'; break;
                                                case '4': *out_carry = '1'; *result = '1'; break;
                                                case '5': *out_carry = '1'; *result = '2'; break;
                                                case '6': *out_carry = '1'; *result = '3'; break;
                                                case '7': *out_carry = '1'; *result = '4'; break;
                                                case '8': *out_carry = '1'; *result = '5'; break;
                                                case '9': *out_carry = '1'; *result = '6'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '8':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '8'; break;
                                                case '1': *out_carry = '0'; *result = '9'; break;
                                                case '2': *out_carry = '1'; *result = '0'; break;
                                                case '3': *out_carry = '1'; *result = '1'; break;
                                                case '4': *out_carry = '1'; *result = '2'; break;
                                                case '5': *out_carry = '1'; *result = '3'; break;
                                                case '6': *out_carry = '1'; *result = '4'; break;
                                                case '7': *out_carry = '1'; *result = '5'; break;
                                                case '8': *out_carry = '1'; *result = '6'; break;
                                                case '9': *out_carry = '1'; *result = '7'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                case '9':        switch (c2)
                                        {
                                                case '0': *out_carry = '0'; *result = '9'; break;
                                                case '1': *out_carry = '1'; *result = '0'; break;
                                                case '2': *out_carry = '1'; *result = '1'; break;
                                                case '3': *out_carry = '1'; *result = '2'; break;
                                                case '4': *out_carry = '1'; *result = '3'; break;
                                                case '5': *out_carry = '1'; *result = '4'; break;
                                                case '6': *out_carry = '1'; *result = '5'; break;
                                                case '7': *out_carry = '1'; *result = '6'; break;
                                                case '8': *out_carry = '1'; *result = '7'; break;
                                                case '9': *out_carry = '1'; *result = '8'; break;
                                                default: ret_val = 0; //Error: c2 out of range
                                        }
                                        break;
                default:        ret_val = 0; //Error: c1 out of range
        }
        switch (in_carry)        //go through "switch case" to get answer without calculate.
        {
                case '0':        break;
                case '1':        switch (*result)
                                        {
                                                case '0': *result = '1'; break;
                                                case '1': *result = '2'; break;
                                                case '2': *result = '3'; break;
                                                case '3': *result = '4'; break;
                                                case '4': *result = '5'; break;
                                                case '5': *result = '6'; break;
                                                case '6': *result = '7'; break;
                                                case '7': *result = '8'; break;
                                                case '8': *result = '9'; break;
                                                case '9': *out_carry = '1'; *result = '0'; break;
                                        }
                                        break;
                default:        ret_val = 0; //Error: in_carry out of range
        }
        if (ret_val != 1)
        {
                *out_carry = '0';
                *result = '0';
        }
        return ret_val;
}

万神fake 发表于 2024-10-8 10:39

厉害啊,虽然不知道有什么用

~零度 发表于 2024-10-8 13:01

之前做过类似的,是模拟小学的时候手算加减乘除的过程,还实现了幂和阶乘的计算。

wangarc 发表于 2024-10-8 14:32

万神fake 发表于 2024-10-8 10:39
厉害啊,虽然不知道有什么用

这个可以计算:
99999999999999999999999999999999 + 0.00000000000000000000000000000001

wangarc 发表于 2024-10-8 14:35

~零度 发表于 2024-10-8 13:01
之前做过类似的,是模拟小学的时候手算加减乘除的过程,还实现了幂和阶乘的计算。

这个加减乘除和列竖式手工计算是一样的。没有高科技,硬来的。

milkyyyyy1 发表于 2024-11-1 15:32

我记得le有个题,是字符数字计算,就有大数问题

tohyueyun 发表于 2024-11-6 02:31

楼主是个勤劳的码农
页: [1]
查看完整版本: <ver0.2>大数计算加减乘除的字符实现