大整数的四则运算

一、 问题描述:
利用线性表相关知识,编程实现一个大整数计算器,该计算器可以完成大整数的加、减、乘、除四则运算。
二、设计与实现:
这里用带头结点的循环双链表的相关操作来模拟大整数计算器的四则运算过程。
#include <stdio.h>
……
三、代码

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <windows.h>

#define MAX 1000



typedef struct Node{

    int data;

    struct Node *prev;

    struct Node *next;

}Node;

typedef struct {

    Node *head;

    int len;

}List;

// 定义带头结点的循环双链表

List *CreateList() {

    List *l = (List*)malloc(sizeof(List)); // 创建头节点

    l->head = (Node*)malloc(sizeof(Node));

    l->head->prev = l->head;

    l->head->next = l->head;

    l->len = 0;

    return l; // 返回头节点指针

}

//在链表前端插入元素

void insertFront(List *l, int data) {

    Node *newNode = (Node*)malloc(sizeof(Node));

    newNode->data = data;

    newNode->prev = l->head->prev;

    newNode->next = l->head;

    l->head->prev->next = newNode;

    l->head->prev = newNode;

    l->len++;

}

//在链表末尾插入元素

void insertEnd(List *l, int data) {

    Node *newNode = (Node*)malloc(sizeof(Node));

    newNode->data = data;

    newNode->next = l->head->next;

    newNode->prev = l->head;

    l->head->next->prev = newNode;

    l->head->next = newNode;

    l->len++;  // 头节点存储数字的位数加1

}

// 从字符串中读取大整数并转换成循环双链表的函数

List *fromString(char *str) {

    List *l =CreateList();

    int len = strlen(str);

    int i;

for (i = len - 1; i >= 0; i--) {

        insertFront(l, str[i] - '0');

    }

    return l;

}

//输出链表

void printList(List *l) {

    Node *p = l->head->prev;

    int cnt=0;

    while(p->data==0) p=p->prev;

while (p != l->head) {

        printf("%d",p->data);

        cnt++;

p = p->prev;

    }

if(cnt==0)

printf("0");

}

//释放链表

void freeList(List *l) {

    Node *p = l->head->next;

    while (p != l->head) {

        Node *tmp = p->next;

        free(p);

        p = tmp;

    }

    free(l->head);

    free(l);

}

//循环双链表的加法运算

List *add(List *a, List *b) {

    List *c =CreateList();

    Node *pa = a->head->next;

    Node *pb = b->head->next;

    int carry = 0; // 进位标志

    while (pa != a->head || pb != b->head) {

        int x = pa == a->head ? 0 : pa->data;

        int y = pb == b->head ? 0 : pb->data;

        int sum = x + y + carry;

        insertFront(c, sum % 10);

        carry = sum / 10;

        if (pa != a->head) pa = pa->next;

        if (pb != b->head) pb = pb->next;

    }

    if (carry > 0) {

        insertFront(c, carry);

    }

    return c;

}

//循环双链表的减法运算

List *sub(List *a, List *b) {

    List *c =CreateList();

    Node *pa = a->head->next;

    Node *pb = b->head->next;

    int borrow = 0;  // 借位标志

    while (pa != a->head) {

        int x = pa->data - borrow;

        int y = pb == b->head ? 0 : pb->data;

        int diff = x - y;

        if (diff < 0) {

            borrow = 1;

            diff += 10;

        } else {

            borrow = 0;

        }

        insertFront(c, diff);

        pa = pa->next;

        if (pb != b->head) pb = pb->next;

    }

    // 去除高位的0

    Node *pc=c->head->prev;

    while(pc->data==0){

     pc=pc->prev;

     c->len--;

}

    c->head->prev=pc;

    pc->next=c->head;

    return c;

}

// 循环双链表的乘法运算

List *mul(List *a, List *b) {

    List *c =CreateList();

    Node *pa = a->head->next;

    Node *pb = b->head->next;

    int cnt=0;

    while (pb != b->head) {

        List *tmp =CreateList();

        int i;

        for(i=0;i<cnt;i++){

         insertFront(tmp,0);

}

cnt++;

        int carry = 0;

        while (pa != a->head) {

            int x = pa->data;

            int y = pb->data;

            int sum= x * y + carry;

            insertFront(tmp,sum% 10);

            carry =sum/ 10;

            pa = pa->next;

        }

        if (carry > 0) {

            insertFront(tmp, carry);

        }

        c = add(c, tmp);

        freeList(tmp);

        pb = pb->next;

        pa = a->head->next;

    }

    return c;

}



//比较链表中数字大小

int cmp(List *a,List *b){

if(a->len>b->len)

return 1;

else if(a->len<b->len)

return 0;

Node *pa=a->head->prev;

Node *pb=b->head->prev;

int n=a->len;

int i;

for(i=0;i<n;i++){

if(pa->data>pb->data)

return 1;

else if(pa->data<pb->data)

return 0;

pa=pa->prev;

pb=pb->prev;

}

return 2;

}

// 循环双链表的除法运算

List *div(List *a, List *b) {

int i;

    List *c =CreateList();

    List *tmp =CreateList();

    List *y=CreateList();

    List *s =CreateList();

    Node *pa=a->head;

    Node *q;

for(i=0;i<b->len;i++) pa=pa->prev;

    q=pa->prev;

while(pa!=a->head){

insertFront(tmp,pa->data);

pa=pa->next;

}

pa=q;



for(i=0;i<=a->len-b->len;i++){

int cnt=0; // 统计商的位数

while(1){

int jud=cmp(b,tmp);

if(jud==1){

insertFront(c,cnt);

break;

}else if(jud==0){

tmp=sub(tmp,b);

cnt++;

}else{

tmp=CreateList();

cnt++;

insertFront(c,cnt);

break;

}

}

insertEnd(tmp,pa->data);

pa=pa->prev;

}

Node *pc=c->head->next;

while(pc->data==0) pc=pc->next;

while(pc!=c->head){

printf("%d",pc->data);

pc=pc->next;

}

    return c;

}

int main() {

int op;

    char s1[MAX], s2[MAX];

    List* num1, *num2;

    printf("****************************************\n");

    printf("|        ★大整数四则运算计算器★      |\n");

    printf("****************************************\n");

    printf("        ||     1--加法运算    ||        \n");

    printf("        ||     2--减法运算    ||        \n");

printf("        ||     3--乘法运算    ||        \n");

printf("        ||     4--除法运算    ||        \n");

printf("        ||     5--重新开始    ||        \n");

printf("        ||     0--退出        ||        \n");

printf("****************************************\n");

printf("■请选择菜单(0-5):");

    scanf("%d",&op);



while(!(op==1||op==2||op==3||op==4||op==5||op==0)){

            printf("■输入选择不明确,请重输:");

            scanf("%d",&op);

    }

    while(1){

        if(op!=5&&op!=0) {

     printf("■请输入第1个长整数:");

     scanf("%s",&s1);

     printf("■请输入第2个长整数:");

     scanf("%s",&s2);

     num1 = fromString(s1);

     num2 = fromString(s2);

     }

if(op==1){

List *res=add(num1,num2);

printf("■%s+%s=",s1,s2);

printList(res);

break;

}else if(op==2){

List *res=sub(num1,num2);

        printf("■%s-%s=",s1,s2);

        printList(res);

        break;

}else if(op==3){

List *res=mul(num1,num2);

        printf("■%s×%s=",s1,s2);

        printList(res);

        break;

}else if(op==4){

printf("■%s÷%s=",s1,s2);

List *res=div(num1,num2);

break;

}else if(op==5){

continue;

}else if(op==0){

printf("欢迎下次使用!");

printf("\n");

exit(0);

}

}

  printf("\n\n");

  printf("※按任意键返回主菜单,继续其他类型运算...※");

  printf("\n\n");

  Sleep(100000);

  return 0;

}

四、运行结果

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
大整数四则运算是指对于超过计算机所能表示的整数范围的数字进行加、减、乘、除等运算。在C语言中,可以通过定义结构体或数组来实现大整数的存储和运算。其中,结构体可以存储大整数的位数和每一位的值,而数组则可以将每一位的值存储在不同的元素中。下面是大整数四则运算的一些基本操作: 1.大整数的输入:可以通过将输入的字符串转换为大整数的形式来实现大整数的输入。具体实现方法可以参考引用中的代码。 2.大整数的输出:可以通过遍历大整数的每一位,将其输出来实现大整数的输出。具体实现方法可以参考引用中的代码。 3.大整数的加法:可以通过模拟手算加法的过程,将两个大整数的每一位相加,并将进位的值加到下一位上来实现大整数的加法。 4.大整数的减法:可以通过模拟手算减法的过程,将两个大整数的每一位相减,并将借位的值减到下一位上来实现大整数的减法。 5.大整数的乘法:可以通过模拟手算乘法的过程,将两个大整数的每一位相乘,并将进位的值加到下一位上来实现大整数的乘法。 6.大整数的除法:可以通过模拟手算除法的过程,将被除数的每一位和商的每一位一一对应,逐位进行除法运算,并将余数带到下一位上来实现大整数的除法。具体实现方法可以参考引用中的代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值