我想尝试的是在600位数下添加两个大数字。
所以我在C中制作struct
但是下面的源代码中存在一些错误。
(实践环境是 GCC编译器和Linux。该工具是 VSCode ,带有 BASH终端。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_SIZE 600
#define SWAP(x,y,t) ((t)=(x), (x)=(y), (y)=(t)) //SWAP preprocessor
#define D_C(x) (x==0 ? 0 : x+'0') //Convert Decimal to Character
#define C_D(x) (x==0 ? 0 : x-'0') //Convert Character to Decimal
/*The structure to save BIG NUMBER*/
typedef struct _BIG_DECIMAL{
unsigned char *data;
int size;
} BIG_DECIMAL;
/*Make string reverse*/
void reverseString(char* s, size_t size) {
char temp;
for (size_t i = 0; i < size / 2; i++) SWAP(s[i], s[(size - 1) - i], temp);
}
/*Create Decimal data in BIG_DECIMAL struct*/
BIG_DECIMAL * createDecimal(unsigned char *str) {
//local variables in func.
size_t size_str;
BIG_DECIMAL * number = malloc(sizeof(BIG_DECIMAL));
//save str in buffer
char buffer[MAX_SIZE] = {'\0',};
strcpy(buffer, str);
//temporary value for size measure.
size_str = strlen(buffer);
printf("%d", size_str);
//Save reversed number data.
reverseString(buffer, size_str);
strcpy(number->data, buffer);
//Save size.
number->size = size_str;
//Return BIG_DECIMAL struct.
return number;
}
/*ADDITION BETWEEN TWO BIG NUMBERS. left argument's size value should be big.*/
BIG_DECIMAL * BD_addition(BIG_DECIMAL *dec1, BIG_DECIMAL *dec2) {
//local variable in this func.
int carry = 0;
BIG_DECIMAL *result = malloc(sizeof(BIG_DECIMAL));
//Adding loop start
for(int i = 0; i < (result -> size); i++) {
int digit_plus;
//if start
if(i < dec2->size) {
//there are digit in both dec so...
digit_plus = C_D(dec1->data[i]) + C_D(dec2->data[i]) + carry;
//nested-if start
if(digit_plus > 10) { //if the carry is occured
carry = digit_plus / 10; //carry can be (> 1)
result->data[i] = D_C(digit_plus % 10);
}
else { //if the carry is not occcured
carry = digit_plus / 10; //carry can be (> 1)
result->data[i] = D_C(digit_plus % 10);
}
//nested-if end
}
else if((i >= (dec2->size)) && (i < ((result->size)-1))){
digit_plus = C_D(dec1->data[i]) + carry;
//nested-if start
if(digit_plus > 10) { //if the carry is occured
carry = digit_plus / 10;
result->data[i] = D_C(digit_plus % 10);
}
else { //if the carry is not occcured
carry = 0;
result->data[i] = D_C(digit_plus);
}
//nested-if end
}
else { //if i == (result->size)-1 (the last index of result->data)
//nested-if start
if(carry > 0) result->data[i] = D_C(carry); //if carry occured
else { //if the carry doesn't occure in the last index of result->data
result->data[i] = D_C(0); //the last index value of result->data is NULL.
--(result->size); //result size - 1
}
//nested-if end
}
//if end
}
//Adding loop end
return result;
}
int main() {
/*data for operand*/
BIG_DECIMAL * op1;
BIG_DECIMAL * op2;
/*data for result*/
BIG_DECIMAL * result;
op1 = createDecimal("123456789");
op2 = createDecimal("12345678");
result = BD_addition(op1,op2);
printf("%s", result->data);
/*DeAllocation*/
free(op1);
free(op2);
free(result);
return 0;
}
此代码导致Segmentation fault
错误。
我认为它可能首先是字符串访问错误,所以我尝试输入所有char*
类型变量,但它不起作用。
答案 0 :(得分:1)
作为评论中的指针,您可以通过为data
分配足够的空间来更正代码,您可以使用strdup
:
/*Create Decimal data in BIG_DECIMAL struct*/
BIG_DECIMAL * createDecimal(unsigned char *str) {
//local variables in func.
size_t size_str;
BIG_DECIMAL * number = malloc(sizeof(BIG_DECIMAL));
//save str in buffer
char buffer[MAX_SIZE] = {'\0',};
strcpy(buffer, str);
//temporary value for size measure.
size_str = strlen(buffer);
//Save reversed number data.
reverseString(buffer, size_str);
/* here: copy buffer in a new allocated memory stored in number->data. */
number->data = strdup(buffer);
//Save size.
number->size = size_str;
//Return BIG_DECIMAL struct.
return number;
}
不要忘记正确释放它们:
/*DeAllocation*/
free(op1->data);
free(op1);
free(op2->data);
free(op2);
您的代码中存在一些错误:BD_addition
函数的开头应如下所示:
BIG_DECIMAL * BD_addition(BIG_DECIMAL *dec1, BIG_DECIMAL *dec2) {
//local variable in this func.
int carry = 0;
BIG_DECIMAL *result = malloc(sizeof(BIG_DECIMAL));
/* compute the size of result */
result->size = (dec1->size < dec2->size) ? dec1->size : dec2->size;
/* take in account an eventual carry */
result->size += 1;
/* allocate */
result->data = malloc(result->size+1);
//Adding loop start
....
您的宏D_C
似乎无效(0
未转换为'0'
)。
答案 1 :(得分:0)
如果你愿意,这里只有一个malloc。
没有struct,strdup,reverse等#include <stdlib.h>
#define toI(x) ((x)-'0')
#define toC(x) ((x)+'0')
#define max(a,b) ((a)>(b)) ? (a):(b)
char *add(char *buf1, char *buf2) {
int size, v1, v2, r, carry=0;
char *ap1, *ep1, *ap2, *ep2, *ap3, *ep3, *rp, *result;
for(ep1=ap1=buf1; *ep1; ep1++);
for(ep2=ap2=buf2; *ep2; ep2++);
size=max(ep2-ap2, ep1-ap1);
ap3=ep3=rp=result=malloc(size+10);
ep3+=size+10;
rp=ep3-1;
*rp='\0';
for(ep1--, ep2--, rp--; ep1>=ap1 || ep2>=ap2; ep1--, ep2--, rp--) {
v1 = ep1>=ap1 ? toI(*ep1) : 0;
v2 = ep2>=ap2 ? toI(*ep2) : 0;
r = v1+v2+carry;
*rp=toC(r%10);
carry=r/10;
}
if(carry!=0) *rp-- = toC(carry);
for(rp++;rp<ep3; rp++, ap3++)
*ap3=*rp;
return result;
}
int main() {
char *result = add("123456789", "12345678");
printf("\n%s\n", result);
free(result);
}