[习题描述] 设计—个实现任意长的整数进行四则运算和幂次运算的演示程序。 [基本要求] 利用双向循环链表实现大数的存储,每个结点含一个整型变量。 [实现提示] 实现原理:任何一个数都可以表示成指数形式,如下所示: N=nEe (0=<n的绝对值<=1,e为10的指数幂) 例如100可以表示成1E2,1001可以表示成1.01E3 ,写出C语言完整代码
时间: 2024-02-14 11:08:58 浏览: 160
用C语言实现大数的四则运算(双向链表)
5星 · 资源好评率100%
以下是基于双向循环链表实现任意长整数四则运算和幂次运算的演示程序的C语言完整代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 定义双向循环链表结点 */
typedef struct Node {
int data;
struct Node *prev;
struct Node *next;
} Node;
/* 定义大数结构体 */
typedef struct BigNum {
Node *head; // 指向双向循环链表的头结点
int sign; // 1表示正数,-1表示负数
} BigNum;
/* 初始化双向循环链表 */
void initList(Node **head) {
*head = (Node*)malloc(sizeof(Node));
(*head)->prev = *head;
(*head)->next = *head;
}
/* 在双向循环链表尾部插入结点 */
void append(Node *head, int data) {
Node *node = (Node*)malloc(sizeof(Node));
node->data = data;
node->prev = head->prev;
node->next = head;
head->prev->next = node;
head->prev = node;
}
/* 删除双向循环链表中的所有结点 */
void clearList(Node *head) {
Node *p = head->next;
while (p != head) {
Node *q = p->next;
free(p);
p = q;
}
head->prev = head;
head->next = head;
}
/* 创建一个大数结构体 */
BigNum *createBigNum() {
BigNum *num = (BigNum*)malloc(sizeof(BigNum));
num->head = NULL;
num->sign = 1;
return num;
}
/* 将字符串形式的大数转换为大数结构体 */
void parseBigNum(char *str, BigNum *num) {
int len = strlen(str);
int i = 0;
if (str[0] == '-') {
num->sign = -1;
i++;
}
initList(&num->head);
while (i < len && str[i] != '.') {
append(num->head, str[i] - '0');
i++;
}
if (i < len) {
i++; // 跳过小数点
while (i < len) {
append(num->head, str[i] - '0');
i++;
}
}
}
/* 将大数结构体转换为字符串形式的大数 */
char *formatBigNum(BigNum *num) {
int len = 0;
Node *p = num->head->next;
while (p != num->head) {
len++;
p = p->next;
}
if (len == 0) {
return "0";
}
char *str = (char*)malloc(len + 2);
int i = 0;
if (num->sign == -1) {
str[i++] = '-';
}
p = num->head->next;
while (p != num->head) {
str[i++] = p->data + '0';
p = p->next;
}
str[i] = '\0';
return str;
}
/* 比较两个大数的大小 */
int compare(BigNum *num1, BigNum *num2) {
Node *p = num1->head->next;
Node *q = num2->head->next;
while (p != num1->head && p->data == 0) {
p = p->next;
}
while (q != num2->head && q->data == 0) {
q = q->next;
}
if (p == num1->head && q == num2->head) {
return 0; // 两个数相等
} else if (p == num1->head && q != num2->head) {
return -1; // num1 < num2
} else if (p != num1->head && q == num2->head) {
return 1; // num1 > num2
} else {
int len1 = 0, len2 = 0;
while (p != num1->head) {
len1++;
p = p->next;
}
while (q != num2->head) {
len2++;
q = q->next;
}
if (len1 < len2) {
return -1; // num1 < num2
} else if (len1 > len2) {
return 1; // num1 > num2
} else {
p = num1->head->next;
q = num2->head->next;
while (p != num1->head && q != num2->head) {
if (p->data < q->data) {
return -1; // num1 < num2
} else if (p->data > q->data) {
return 1; // num1 > num2
} else {
p = p->next;
q = q->next;
}
}
return 0; // 两个数相等
}
}
}
/* 对两个大数取绝对值后进行比较 */
int compareAbs(BigNum *num1, BigNum *num2) {
BigNum *abs1 = createBigNum();
BigNum *abs2 = createBigNum();
abs1->head = num1->head;
abs2->head = num2->head;
abs1->sign = 1;
abs2->sign = 1;
int result = compare(abs1, abs2);
free(abs1);
free(abs2);
return result;
}
/* 大数加法 */
BigNum *add(BigNum *num1, BigNum *num2) {
BigNum *result = createBigNum();
Node *p = num1->head->prev;
Node *q = num2->head->prev;
int carry = 0; // 进位
while (p != num1->head || q != num2->head) {
int sum = carry;
if (p != num1->head) {
sum += p->data;
p = p->prev;
}
if (q != num2->head) {
sum += q->data;
q = q->prev;
}
append(result->head, sum % 10);
carry = sum / 10;
}
if (carry > 0) {
append(result->head, carry);
}
// 去掉前导0
while (result->head->next != result->head && result->head->next->data == 0) {
Node *temp = result->head->next;
result->head->next = temp->next;
temp->next->prev = result->head;
free(temp);
}
return result;
}
/* 大数减法 */
BigNum *subtract(BigNum *num1, BigNum *num2) {
BigNum *result = createBigNum();
if (compareAbs(num1, num2) < 0) {
result->sign = -1;
BigNum *temp = num1;
num1 = num2;
num2 = temp;
}
Node *p = num1->head->prev;
Node *q = num2->head->prev;
int borrow = 0; // 借位
while (p != num1->head || q != num2->head) {
int diff = borrow;
if (p != num1->head) {
diff += p->data;
p = p->prev;
}
if (q != num2->head) {
diff -= q->data;
q = q->prev;
}
if (diff < 0) {
diff += 10;
borrow = -1;
} else {
borrow = 0;
}
append(result->head, diff);
}
// 去掉前导0
while (result->head->next != result->head && result->head->next->data == 0) {
Node *temp = result->head->next;
result->head->next = temp->next;
temp->next->prev = result->head;
free(temp);
}
return result;
}
/* 大数乘法 */
BigNum *multiply(BigNum *num1, BigNum *num2) {
BigNum *result = createBigNum();
Node *p = num1->head->prev;
while (p != num1->head) {
int carry = 0;
Node *q = num2->head->prev;
BigNum *temp = createBigNum();
while (q != num2->head) {
int product = p->data * q->data + carry;
append(temp->head, product % 10);
carry = product / 10;
q = q->prev;
}
if (carry > 0) {
append(temp->head, carry);
}
// 在temp结尾添加len个0
int len = num1->head->prev->data - p->data;
while (len > 0) {
append(temp->head, 0);
len--;
}
result = add(result, temp);
free(temp);
p = p->prev;
}
if (num1->sign != num2->sign) {
result->sign = -1;
}
return result;
}
/* 大数除法 */
BigNum *divide(BigNum *num1, BigNum *num2) {
BigNum *result = createBigNum();
BigNum *remain = createBigNum();
remain->head = num1->head;
remain->sign = 1;
while (compareAbs(remain, num2) >= 0) {
BigNum *temp = createBigNum();
Node *p = remain->head->next;
while (compareAbs(temp, num2) < 0 && p != remain->head) {
append(temp->head, p->data);
p = p->next;
}
int quotient = 0;
while (compareAbs(temp, num2) >= 0) {
temp = subtract(temp, num2);
quotient++;
}
append(result->head, quotient);
clearList(remain->head);
p = temp->head->next;
while (p != temp->head) {
append(remain->head, p->data);
p = p->next;
}
remain->sign = 1;
free(temp);
}
free(remain);
if (num1->sign != num2->sign) {
result->sign = -1;
}
// 去掉前导0
while (result->head->next != result->head && result->head->next->data == 0) {
Node *temp = result->head->next;
result->head->next = temp->next;
temp->next->prev = result->head;
free(temp);
}
return result;
}
/* 大数幂次运算 */
BigNum *power(BigNum *num, int exp) {
BigNum *result = createBigNum();
append(result->head, 1);
while (exp > 0) {
if (exp % 2 == 1) {
result = multiply(result, num);
}
num = multiply(num, num);
exp /= 2;
}
return result;
}
int main() {
char str1[101], str2[101];
scanf("%s %s", str1, str2);
BigNum *num1 = createBigNum();
BigNum *num2 = createBigNum();
parseBigNum(str1, num1);
parseBigNum(str2, num2);
BigNum *sum = add(num1, num2);
BigNum *diff = subtract(num1, num2);
BigNum *product = multiply(num1, num2);
BigNum *quotient = divide(num1, num2);
BigNum *power_num = power(num1, 3);
printf("%s + %s = %s\n", str1, str2, formatBigNum(sum));
printf("%s - %s = %s\n", str1, str2, formatBigNum(diff));
printf("%s * %s = %s\n", str1, str2, formatBigNum(product));
printf("%s / %s = %s\n", str1, str2, formatBigNum(quotient));
printf("%s ^ 3 = %s\n", str1, formatBigNum(power_num));
free(num1);
free(num2);
free(sum);
free(diff);
free(product);
free(quotient);
free(power_num);
return 0;
}
```
需要注意的是,在进行大数除法运算时,除数不能为0,需要进行错误处理。
阅读全文