ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C语言 双向链表处理大数加减

2021-03-24 13:04:09  阅读:165  来源: 互联网

标签:digit p1 struct 大数 UBigNumber pUBN C语言 链表 pHead


处理无符号大数加减

处理有符号大数加减

处理有符号大数加减

1.定义的结构体

struct Node
{
    int digit;  //数字
    struct Node *next, *prev;  //前后指针
};

struct UBigNumber
{
    int digitCount;  //位数
    struct Node *pHead, *pTail;  //指向头结点和尾结点
};

2.定义的函数:

//动态分配1个结点,返回结点指针
//当分配失败时,简化程序,退出运行
struct Node *_NewNode();

//表示无符号大数用带头结点的双向链表
void _InitUBN(struct UBigNumber *pUBN);

//输入无符号大数
struct UBigNumber InputUBN();

//无符号大数尾部添加1位数字
void _AppendDigit(struct UBigNumber *pUBN, int digit);

//无符号大数首部添加1位数字
void _AppendFrontDigit(struct UBigNumber *pUBN, int digit);

//无符号大数的规范表示,去除高位多余的0,至少含1位数字
void _Normalize(struct UBigNumber *pUBN);

//两个无符号大数相加
struct UBigNumber AddUBN(struct UBigNumber *pA, struct UBigNumber *pB);

//无符号整数相减
struct UBigNumber SubUBN(struct UBigNumber *pA, struct UBigNumber *pB);

//打印无符号大数
void PrintUBN(struct UBigNumber ubn);

//销毁无符号大数,释放空间
void DestroyUBN(struct UBigNumber *pA);

  1. 函数实现代码:
//动态分配1个结点,返回结点指针
//当分配失败时,简化程序,退出运行
struct Node *_NewNode()
{
    struct Node *p;
    p = (struct Node*)malloc(sizeof(struct Node));
    if(p == NULL)  //分配失败
    {
        printf("Error:out of memory\n");
        exit(-1);  //简化程序,退出运行
    }
    return p;

}


//建立表示无符号大数用带头结点的双向链表
void _InitUBN(struct UBigNumber *pUBN)
{
    struct Node *p = _NewNode();
    pUBN->pHead = pUBN->pTail = p;  //建立头结点
    p->next = p->prev = NULL;
    pUBN->digitCount = 0;
}


//输入无符号大数
struct UBigNumber InputUBN()
{
    struct UBigNumber result;
    _InitUBN(&result);

    char ch;
    //跳过非数字字符
    do
        ch = getchar();
    while(ch < '0' || ch > '9');
    while(ch >= '0' && ch <= '9')
    {
        _AppendDigit(&result, ch-'0');  //添加1位
        ch = getchar();
    }
    _Normalize(&result);
    return result;
}


//无符号大数尾部添加1位数字
void _AppendDigit(struct UBigNumber *pUBN, int digit)
{  //原来只有一个高位0
    if(pUBN->digitCount == 1 && pUBN->pTail->digit == 0)
    {
        pUBN->pTail->digit = digit;  //位数不变,数值为0
        return;
    }
    struct Node *p = _NewNode();  //申请新结点
    p->digit = digit;  //设置结点数值
    p->next = NULL;  //修改双向链表,将新结点添加到尾部
    p->prev = pUBN->pTail;
    pUBN->pTail->next = p;
    pUBN->pTail = p;
    ++pUBN->digitCount;  //修改位数
}


//无符号大数首部添加1位数字
void _AppendFrontDigit(struct UBigNumber *pUBN, int digit)
{
    struct Node *p = _NewNode();  //申请新结点
    p->digit = digit;  //设置结点数值
    p->next = pUBN->pHead->next;  //修改双向链表,将新结点添加在头结点后
    if(p->next != NULL)
        p->next->prev = p;
    p->prev = pUBN->pHead;
    pUBN->pHead->next = p;
    if(pUBN->pTail == pUBN->pHead)
        pUBN->pTail = p;  //当原来只有头结点时,新结点也是尾结点
    ++pUBN->digitCount;  //修改位数
}


//无符号大数的规范表示,去除高位多余的0,至少含1位数字
void _Normalize(struct UBigNumber *pUBN)
{
    if(pUBN->digitCount == 0)
        _AppendDigit(pUBN, 0);
    while(pUBN->digitCount > 1 && pUBN->pHead->next->digit == 0)
    {   //去除高位多余的0
        struct Node *p;
        p = pUBN->pHead->next;  //待删除的结点
        pUBN->pHead->next = p->next;  //正向链表中删除
        p->next->prev = pUBN->pHead;  //反向链表中删除
        free(p);  //释放结点
        --pUBN->digitCount;  //调整位数
    }
}


//两个无符号大数相加
struct UBigNumber AddUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct UBigNumber result, *pResult = &result;
    _InitUBN(pResult);
    int iCarry = 0;  //进位,初始0
    struct Node *p1, *p2;
    p1 = pA->pTail;  //从低位开始处理
    p2 = pB->pTail;
    while(p1 != pA->pHead && p2 != pB->pHead)  //两数相同位处理
    {
        int digit = p1->digit + p2->digit + iCarry;
        iCarry = digit / 10;  //新进位
        digit %= 10;  //当前结果位
        _AppendFrontDigit(pResult, digit);  //添加至结果最高位
        p1 = p1->prev;  //准备处理前一位
        p2 = p2->prev;
    }
    while(p1 != pA->pHead)  //第一位大数剩余位处理
    {
        int digit = p1->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
    }
    while(p2 != pB->pHead)  //第二位大数剩余位处理
    {
        int digit = p2->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p2 = p2->prev;
    }
    if(iCarry != 0)  //最后进位处理
        _AppendFrontDigit(pResult, iCarry);
    return result;
}


//两个无符号大数相减
struct UBigNumber SubUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct UBigNumber result, *pResult = &result;
    _InitUBN(pResult);
    int iCarry = 0;  //退位,初始0
    struct Node *p1, *p2;
    p1 = pA->pTail;  //从低位开始处理
    p2 = pB->pTail;
    while(p1 != pA->pHead && p2 != pB->pHead)  //两数相同位处理
    {
        int digit = p1->digit - p2->digit - iCarry;
        iCarry = 0; //初始化
        if(digit < 0)
        {
            digit += 10;  
            iCarry = 1;  //前一位退1
        }
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
        p2 = p2->prev;
    }
    while(p1 != pA->pHead)  //最后退位处理
    {
        int digit = p1->digit - iCarry;
        iCarry = 0;
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
    }
    _Normalize(pResult);
    return result;
}


//打印无符号大数
void PrintUBN(struct UBigNumber ubn)
{  //断言:至少有1位数字
    assert(ubn.digitCount > 0 && ubn.pHead->next != NULL);
    struct Node *la = ubn.pHead->next;  //头结点无数据,跳过
    while(la)
    {
        printf("%d",la->digit);
        la = la->next;
    }
}


//销毁无符号大数,释放空间
void DestroyUBN(struct UBigNumber *pUBN)
{
    while(pUBN->pHead != NULL)
    {
        struct Node *p = pUBN->pHead;  //待删除结点
        pUBN->pHead = p->next;  //尾指针前移
        free(p);  //释放结点
    }
}

4.完整代码

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>


struct Node
{
    int digit;  //数字
    struct Node *next, *prev;  //前后指针
};

struct UBigNumber
{
    int digitCount;  //位数
    struct Node *pHead, *pTail;  //指向头结点和尾结点
};


//动态分配1个结点,返回结点指针
//当分配失败时,简化程序,退出运行
struct Node *_NewNode();
//表示无符号大数用带头结点的双向链表
void _InitUBN(struct UBigNumber *pUBN);
//输入无符号大数
struct UBigNumber InputUBN();
//无符号大数尾部添加1位数字
void _AppendDigit(struct UBigNumber *pUBN, int digit);
//无符号大数首部添加1位数字
void _AppendFrontDigit(struct UBigNumber *pUBN, int digit);
//无符号大数的规范表示,去除高位多余的0,至少含1位数字
void _Normalize(struct UBigNumber *pUBN);
//两个无符号大数相加
struct UBigNumber AddUBN(struct UBigNumber *pA, struct UBigNumber *pB);
//无符号整数相减
struct UBigNumber SubUBN(struct UBigNumber *pA, struct UBigNumber *pB);
//打印无符号大数
void PrintUBN(struct UBigNumber ubn);
//销毁无符号大数,释放空间
void DestroyUBN(struct UBigNumber *pA);


int main()
{
    struct UBigNumber A, B, C, D;
    A = InputUBN();
    B = InputUBN();
    C = AddUBN(&A, &B);
    D = SubUBN(&A, &B);

    PrintUBN(A);
    printf("+");
    PrintUBN(B);
    printf("=");
    PrintUBN(C);
    printf("\n");

    PrintUBN(A);
    printf("-");
    PrintUBN(B);
    printf("=");
    PrintUBN(D);

    DestroyUBN(&A);
    DestroyUBN(&B);
    DestroyUBN(&C);
    DestroyUBN(&D);

    return 0;
}


struct Node *_NewNode()
{
    struct Node *p;
    p = (struct Node*)malloc(sizeof(struct Node));
    if(p == NULL)  //分配失败
    {
        printf("Error:out of memory\n");
        exit(-1);  //简化程序,退出运行
    }
    return p;

}


//建立表示无符号大数用带头结点的双向链表
void _InitUBN(struct UBigNumber *pUBN)
{
    struct Node *p = _NewNode();
    pUBN->pHead = pUBN->pTail = p;  //建立头结点
    p->next = p->prev = NULL;
    pUBN->digitCount = 0;
}


//输入无符号大数
struct UBigNumber InputUBN()
{
    struct UBigNumber result;
    _InitUBN(&result);

    char ch;
    //跳过非数字字符
    do
        ch = getchar();
    while(ch < '0' || ch > '9');
    while(ch >= '0' && ch <= '9')
    {
        _AppendDigit(&result, ch-'0');  //添加1位
        ch = getchar();
    }
    _Normalize(&result);
    return result;
}


//无符号大数尾部添加1位数字
void _AppendDigit(struct UBigNumber *pUBN, int digit)
{  //原来只有一个高位0
    if(pUBN->digitCount == 1 && pUBN->pTail->digit == 0)
    {
        pUBN->pTail->digit = digit;  //位数不变,数值为0
        return;
    }
    struct Node *p = _NewNode();  //申请新结点
    p->digit = digit;  //设置结点数值
    p->next = NULL;  //修改双向链表,将新结点添加到尾部
    p->prev = pUBN->pTail;
    pUBN->pTail->next = p;
    pUBN->pTail = p;
    ++pUBN->digitCount;  //修改位数
}


//无符号大数首部添加1位数字
void _AppendFrontDigit(struct UBigNumber *pUBN, int digit)
{
    struct Node *p = _NewNode();  //申请新结点
    p->digit = digit;  //设置结点数值
    p->next = pUBN->pHead->next;  //修改双向链表,将新结点添加在头结点后
    if(p->next != NULL)
        p->next->prev = p;
    p->prev = pUBN->pHead;
    pUBN->pHead->next = p;
    if(pUBN->pTail == pUBN->pHead)
        pUBN->pTail = p;  //当原来只有头结点时,新结点也是尾结点
    ++pUBN->digitCount;  //修改位数
}


//无符号大数的规范表示,去除高位多余的0,至少含1位数字
void _Normalize(struct UBigNumber *pUBN)
{
    if(pUBN->digitCount == 0)
        _AppendDigit(pUBN, 0);
    while(pUBN->digitCount > 1 && pUBN->pHead->next->digit == 0)
    {   //去除高位多余的0
        struct Node *p;
        p = pUBN->pHead->next;  //待删除的结点
        pUBN->pHead->next = p->next;  //正向链表中删除
        p->next->prev = pUBN->pHead;  //反向链表中删除
        free(p);  //释放结点
        --pUBN->digitCount;  //调整位数
    }
}


//两个无符号大数相加
struct UBigNumber AddUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct UBigNumber result, *pResult = &result;
    _InitUBN(pResult);
    int iCarry = 0;  //进位,初始0
    struct Node *p1, *p2;
    p1 = pA->pTail;  //从低位开始处理
    p2 = pB->pTail;
    while(p1 != pA->pHead && p2 != pB->pHead)  //两数相同位处理
    {
        int digit = p1->digit + p2->digit + iCarry;
        iCarry = digit / 10;  //新进位
        digit %= 10;  //当前结果位
        _AppendFrontDigit(pResult, digit);  //添加至结果最高位
        p1 = p1->prev;  //准备处理前一位
        p2 = p2->prev;
    }
    while(p1 != pA->pHead)  //第一位大数剩余位处理
    {
        int digit = p1->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
    }
    while(p2 != pB->pHead)  //第二位大数剩余位处理
    {
        int digit = p2->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p2 = p2->prev;
    }
    if(iCarry != 0)  //最后进位处理
        _AppendFrontDigit(pResult, iCarry);
    return result;
}


//两个无符号大数相减
struct UBigNumber SubUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct UBigNumber result, *pResult = &result;
    _InitUBN(pResult);
    int iCarry = 0;  //退位,初始0
    struct Node *p1, *p2;
    p1 = pA->pTail;  //从低位开始处理
    p2 = pB->pTail;
    while(p1 != pA->pHead && p2 != pB->pHead)  //两数相同位处理
    {
        int digit = p1->digit - p2->digit - iCarry;
        iCarry = 0; //初始化
        if(digit < 0)
        {
            digit += 10;  
            iCarry = 1;  //前一位退1
        }
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
        p2 = p2->prev;
    }
    while(p1 != pA->pHead)  //最后退位处理
    {
        int digit = p1->digit - iCarry;
        iCarry = 0;
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
    }
    _Normalize(pResult);
    return result;
}


//打印无符号大数
void PrintUBN(struct UBigNumber ubn)
{  //断言:至少有1位数字
    assert(ubn.digitCount > 0 && ubn.pHead->next != NULL);
    struct Node *la = ubn.pHead->next;  //头结点无数据,跳过
    while(la)
    {
        printf("%d",la->digit);
        la = la->next;
    }
}


//销毁无符号大数,释放空间
void DestroyUBN(struct UBigNumber *pUBN)
{
    while(pUBN->pHead != NULL)
    {
        struct Node *p = pUBN->pHead;  //待删除结点
        pUBN->pHead = p->next;  //尾指针前移
        free(p);  //释放结点
    }
}


处理有符号大数加减

  1. 定义的函数(与无符号相比有修改或增加的函数)

//输入有符号大数
struct UBigNumber InputUBN();

//大数绝对值比较大小
int CmpUBN(struct UBigNumber *pA, struct UBigNumber *pB);

//打印有符号大数
void PrintUBN(struct UBigNumber ubn);

  1. 函数的实现
//输入有符号大数
struct UBigNumber InputUBN()
{
    struct UBigNumber result;
    _InitUBN(&result);

    char ch;
    do
    {
        ch = getchar();
        if(ch == '-')
        {
            result.pHead->digit = '-';  //存储负号
            ch = getchar();
            break;
        }
        else
            result.pHead->digit = '+';  //存储正号
    }while(ch < '0' || ch > '9');
    while(ch >= '0' && ch <= '9')
    {
        _AppendDigit(&result, ch-'0');
        ch = getchar();
    }
    _Normalize(&result);
    return result;
}

//两个大数绝对值比较大小
int  CmpUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct Node *p1, *p2;
    //先比较位数
    if(pA->digitCount > pB->digitCount)
        return 0;  //0标记pA大于等于pB
    else
    {
        p1 = pA->pHead->next;
        p2 = pB->pHead->next;
        while(p1 != NULL)  //位数相同,只需判断p1与p2其中一个即可
        {
            if(p1 < p2)
                return 1;//1标记pA小于pB
            p1 = p1->next;
            p2 = p2->next;
        }
    }
    return 0;  //pA与pB相等
}

//打印有符号大数
void PrintUBN(struct UBigNumber ubn)
{
    assert(ubn.digitCount > 0 && ubn.pHead->next != NULL);
    //若负数,打印负号
    if(ubn.pHead->digit == '-')
        printf("%c", ubn.pHead->digit);
    //打印数字
    struct Node *la = ubn.pHead->next;
    while(la)
    {
        printf("%d",la->digit);
        la = la->next;
    }
}
  1. 完整代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>


struct Node
{
    int digit;  //数字
    struct Node *next, *prev;  //前后指针
};

struct UBigNumber
{
    int digitCount;  //位数
    struct Node *pHead, *pTail;  //指向头结点和尾结点
};

//动态分配1个结点,返回结点指针
//当分配失败时,简化程序,退出运行
struct Node *_NewNode();
//表示大数用带头结点的双向链表
void _InitUBN(struct UBigNumber *pUBN);
//输入有符号大数
struct UBigNumber InputUBN();
//大数尾部添加1位数字
void _AppendDigit(struct UBigNumber *pUBN, int digit);
//大数首部添加1位数字
void _AppendFrontDigit(struct UBigNumber *pUBN, int digit);
//大数的规范表示,去除高位多余的0,至少含1位数字
void _Normalize(struct UBigNumber *pUBN);
//大数绝对值比较大小
int  CmpUBN(struct UBigNumber *pA, struct UBigNumber *pB);
//两个有符号大数相加
struct UBigNumber AddUBN(struct UBigNumber *pA, struct UBigNumber *pB);
//无符号整数相减
struct UBigNumber SubUBN(struct UBigNumber *pA, struct UBigNumber *pB);
//打印有符号大数
void PrintUBN(struct UBigNumber ubn);
//销毁有符号大数,释放空间
void DestroyUBN(struct UBigNumber *pA);


int main()
{
    struct UBigNumber A, B, C, D;
    A = InputUBN();
    B = InputUBN();
    //输入两个正数
    if(A.pHead->digit == '+' && B.pHead->digit == '+') 
    {
        if(CmpUBN(&A, &B))
        {   //A绝对值比B绝对值小
            C = AddUBN(&A, &B);
            C.pHead->digit = '+';
            D = SubUBN(&B, &A);
            D.pHead->digit = '-';
        }
        else
        {
            C = AddUBN(&A, &B);
            C.pHead->digit = '+';
            D = SubUBN(&A, &B);
            D.pHead->digit = '+';
        }

    }
    //输入第一个正数,第二个负数
    else if(A.pHead->digit == '+' && B.pHead->digit == '-')
    {
       if(CmpUBN(&A, &B))
        {   //A绝对值比B绝对值小
            C = SubUBN(&B, &A);
            C.pHead->digit = '-';
            D = AddUBN(&B, &A);
            D.pHead->digit = '+';
        }
        else
        {
            C = SubUBN(&A, &B);
            C.pHead->digit = '+';
            D = AddUBN(&A, &B);
            D.pHead->digit = '+';
        }
    }
    //输入第一个负数,第二个正数
    else if(A.pHead->digit == '-' && B.pHead->digit == '+')
    {
       if(CmpUBN(&A, &B))
        {   //A绝对值比B绝对值小
            C = SubUBN(&B, &A);
            C.pHead->digit = '+';
            D = AddUBN(&B, &A);
            D.pHead->digit = '-';
        }
        else
        {
            C = SubUBN(&A, &B);
            C.pHead->digit = '-';
            D = AddUBN(&A, &B);
            D.pHead->digit = '-';
        }
    }
    //输入第一个负数,第二个负数
    else if(A.pHead->digit == '-' && B.pHead->digit == '-')
    {
       if(CmpUBN(&A, &B))
        {   //A绝对值比B绝对值小
            C = AddUBN(&B, &A);
            C.pHead->digit = '-';
            D = SubUBN(&B, &A);
            D.pHead->digit = '+';
        }
        else
        {
            C = AddUBN(&A, &B);
            C.pHead->digit = '-';
            D = SubUBN(&A, &B);
            D.pHead->digit = '-';
        }
    }


    PrintUBN(C);

    printf("\n");

    PrintUBN(D);

    DestroyUBN(&A);
    DestroyUBN(&B);
    DestroyUBN(&C);
    DestroyUBN(&D);

    return 0;
}


//动态分配1个结点,返回结点指针
//当分配失败时,简化程序,退出运行
struct Node *_NewNode()
{
    struct Node *p;
    p = (struct Node*)malloc(sizeof(struct Node));
    if(p == NULL)
    {
        printf("Error:out of memory\n");
        exit(-1);
    }
    return p;

}


//表示大数用带头结点的双向链表
void _InitUBN(struct UBigNumber *pUBN)
{
    struct Node *p = _NewNode();
    pUBN->pHead = pUBN->pTail = p;
    p->next = p->prev = NULL;
    pUBN->digitCount = 0;
}


//输入有符号大数
struct UBigNumber InputUBN()
{
    struct UBigNumber result;
    _InitUBN(&result);

    char ch;
    do
    {
        ch = getchar();
        if(ch == '-')
        {
            result.pHead->digit = '-';  //存储负号
            ch = getchar();
            break;
        }
        else
            result.pHead->digit = '+';  //存储正号
    }while(ch < '0' || ch > '9');
    while(ch >= '0' && ch <= '9')
    {
        _AppendDigit(&result, ch-'0');
        ch = getchar();
    }
    _Normalize(&result);
    return result;
}


//大数尾部添加1位数字
void _AppendDigit(struct UBigNumber *pUBN, int digit)
{
    if(pUBN->digitCount == 1 && pUBN->pTail->digit == 0)
    {
        pUBN->pTail->digit = digit;
        return;
    }
    struct Node *p = _NewNode();
    p->digit = digit;
    p->next = NULL;
    p->prev = pUBN->pTail;
    pUBN->pTail->next = p;
    pUBN->pTail = p;
    ++pUBN->digitCount;
}


//大数首部添加1位数字
void _AppendFrontDigit(struct UBigNumber *pUBN, int digit)
{
    struct Node *p = _NewNode();
    p->digit = digit;
    p->next = pUBN->pHead->next;
    if(p->next != NULL)
        p->next->prev = p;
    p->prev = pUBN->pHead;
    pUBN->pHead->next = p;
    if(pUBN->pTail == pUBN->pHead)
        pUBN->pTail = p;
    ++pUBN->digitCount;
}


//大数的规范表示,去除高位多余的0,至少含1位数字
void _Normalize(struct UBigNumber *pUBN)
{
    if(pUBN->digitCount == 0)
        _AppendDigit(pUBN, 0);
    while(pUBN->digitCount > 1 && pUBN->pHead->next->digit == 0)
    {
        struct Node *p;
        p = pUBN->pHead->next;
        pUBN->pHead->next = p->next;
        p->next->prev = pUBN->pHead;
        free(p);
        --pUBN->digitCount;
    }
}


//两个大数绝对值比较大小
int  CmpUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct Node *p1, *p2;
    //先比较位数
    if(pA->digitCount > pB->digitCount)
        return 0;  //0标记pA大于等于pB
    else
    {
        p1 = pA->pHead->next;
        p2 = pB->pHead->next;
        while(p1 != NULL)  //位数相同,只需判断p1与p2其中一个即可
        {
            if(p1 < p2)
                return 1;//1标记pA小于pB
            p1 = p1->next;
            p2 = p2->next;
        }
    }
    return 0;  //pA与pB相等
}


//两个大数相加
struct UBigNumber AddUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct UBigNumber result, *pResult = &result;
    _InitUBN(pResult);
    int iCarry = 0;
    struct Node *p1, *p2;
    p1 = pA->pTail;
    p2 = pB->pTail;
    while(p1 != pA->pHead && p2 != pB->pHead)
    {
        int digit = p1->digit + p2->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
        p2 = p2->prev;
    }
    while(p1 != pA->pHead)
    {
        int digit = p1->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
    }
    while(p2 != pB->pHead)
    {
        int digit = p2->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p2 = p2->prev;
    }
    if(iCarry != 0)
        _AppendFrontDigit(pResult, iCarry);
    return result;
}


//两个大数相减
struct UBigNumber SubUBN(struct UBigNumber *pA, struct UBigNumber *pB)
{
    struct UBigNumber result, *pResult = &result;
    _InitUBN(pResult);
    int iCarry = 0;
    struct Node *p1, *p2;
    p1 = pA->pTail;
    p2 = pB->pTail;
    while(p1 != pA->pHead && p2 != pB->pHead)
    {
        int digit = p1->digit - p2->digit - iCarry;
        iCarry = 0;
        if(digit < 0)
        {
            digit += 10;
            iCarry = 1;
        }
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
        p2 = p2->prev;
    }
    while(p1 != pA->pHead)
    {
        int digit = p1->digit - iCarry;
        iCarry = 0;
        _AppendFrontDigit(pResult, digit);
        p1 = p1->prev;
    }
    _Normalize(pResult);
    while(p2 != pB->pHead)
    {
        int digit = p2->digit + iCarry;
        iCarry = digit / 10;
        digit %= 10;
        _AppendFrontDigit(pResult, digit);
        p2 = p2->prev;
    }
    if(iCarry != 0)
        _AppendFrontDigit(pResult, iCarry);
    return result;
}


//打印有符号大数
void PrintUBN(struct UBigNumber ubn)
{
    assert(ubn.digitCount > 0 && ubn.pHead->next != NULL);
    //若负数,打印负号
    if(ubn.pHead->digit == '-')
        printf("%c", ubn.pHead->digit);
    //打印数字
    struct Node *la = ubn.pHead->next;
    while(la)
    {
        printf("%d",la->digit);
        la = la->next;
    }
}


//销毁大数,释放空间
void DestroyUBN(struct UBigNumber *pUBN)
{
    while(pUBN->pHead != NULL)
    {
        struct Node *p = pUBN->pHead;
        pUBN->pHead = p->next;
        free(p);
    }
}











标签:digit,p1,struct,大数,UBigNumber,pUBN,C语言,链表,pHead
来源: https://blog.csdn.net/heng0123/article/details/115172463

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有