If I had two strings:
a = \"1234\"
b = \"4321\"
I could add the two numbers together like this:
for(i=0; i
cited from C - Adding the numbers in 2 strings together if a different length answer, I write a more readable code:
void str_reverse(char *beg, char *end){
if(!beg || !end)return;
char cTmp;
while(beg < end){
cTmp = *beg;
*beg++ = *end;
*end-- = cTmp;
}
}
#define c2d(c) (c - '0')
#define d2c(d) (d + '0')
void str_add(const char* s1, const char* s2, char* s_ret){
int s1_len = strlen(s1);
int s2_len = strlen(s2);
int max_len = s1_len;
int min_len = s2_len;
const char *ps_max = s1;
const char *ps_min = s2;
if(s2_len > s1_len){
ps_min = s1;min_len = s1_len;
ps_max = s2;max_len = s2_len;
}
int carry = 0;
int i, j = 0;
for (i = max_len - 1; i >= 0; --i) {
// this wrong-prone
int idx = (i - max_len + min_len) >=0 ? (i - max_len + min_len) : -1;
int sum = c2d(ps_max[i]) + (idx >=0 ? c2d(ps_min[idx]) : 0) + carry;
carry = sum / 10;
sum = sum % 10;
s_ret[j++] = d2c(sum);
}
if(carry)s_ret[j] = '1';
str_reverse(s_ret, s_ret + strlen(s_ret) - 1);
}
test code as below:
void test_str_str_add(){
char s1[] = "123";
char s2[] = "456";
char s3[10] = {'\0'};
str_add(s1, s2, s3);
std::cout<<s3<<std::endl;
char s4[] = "456789";
char s5[10] = {'\0'};
str_add(s1, s4, s5);
std::cout<<s5<<std::endl;
char s7[] = "99999";
char s8[] = "21";
char s9[10] = {'\0'};
str_add(s7, s8, s9);
std::cout<<s9<<std::endl;
}
output:
579
456912
100020
int getcharval(const char *s, int idx) {
if (idx < strlen(s))
return s[strlen(s) - idx - 1] - 48;
return 0;
}
void add() {
const char *a = "1234";
const char *b = "13210";
char answer[256];
int i, wa=strlen(a), wb=strlen(b), width, sum, carry;
width = wa > wb ? wa : wb;
for(i=0; i<width; i++){
char ca = getcharval(a, i);
char cb = getcharval(b, i);
printf("%d %d\n", ca, cb);
sum = ca + cb + carry;
carry = 0;
if(sum > 9){
carry = 1;
sum-=10;
}
answer[i] = sum+48;
}
if(carry) answer[i++] = carry+48;
answer[i]= 0;
for (i = 0; i < strlen(answer) / 2; i++) {
char t = answer[i];
answer[i] = answer[strlen(answer) - i - 1];
answer[strlen(answer) - i - 1] = t;
}
printf("%s\n", answer);
}
int num(char x,int len){
if(len <0)
return 0;
return ((x=='1') ? 1 : (x=='2') ? 2 : (x=='3') ? 3 : (x=='4') ? 4 : (x=='5') ? 5 : (x=='6') ? 6 : (x=='7') ? 7 : (x=='8') ? 8 : 9);
}
int main(){
int result[100];
int i=0;
char num1[] = "123456789123456789";
char num2[] = "1234567811111111111111111111";
int carry = 0;
int l1= strlen(num1)-1;
int l2 = strlen(num2)-1;
int result1;
while(1){
if(l1 < 0 && l2 <0 && carry == 0)
break;
result1 = num(num1[l1],l1) + num(num2[l2],l2);
l1--;
l2--;
if(carry>0){
result1 +=carry;
carry = 0;
}
carry = result1 / 10;
result[i] = (result1 % 10);
i++;
}
i--;
printf("\n");
while(i>=0){
printf("%d",result[i]);
i--;
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define c2d(c) (c-'0')
#define d2c(c) (c+'0')
char* add(const char *a, const char *b, char *ans){
int alen, blen;
int i, carry=0;
char *wk;
char *awk=strdup(a);
char *bwk=strdup(b);
alen=strlen(strrev(awk));
blen=strlen(strrev(bwk));
if(alen<blen){
alen ^= blen;blen ^= alen;alen ^= blen;//swap
wk = awk ; awk = bwk ; bwk = wk;
}
ans[alen+1]=ans[alen]='\0';
for(i=0;i<alen;++i){
int sum = c2d(awk[i])+(i<blen ? c2d(bwk[i]): 0)+carry;
ans[i] = d2c(sum % 10);
carry = sum / 10;
}
if(carry){
ans[i++]='1';
}
free(awk);
free(bwk);
return strrev(ans);
}
int main(){
const char *a="12345";
const char *b="4321";
char ans[6];
printf("{%s}+{%s}={%s}\n", a, b, add(a,b, ans));
return 0;
}
If you insist on using the "elementary school addition", find the length of both strings, advance to their ends, and then move back until the shorter string's length is exhausted. Then continue moving in only the longer string, assuming that the remaining digits of the shorter string are zeros:
12345
04321
You need to move all the way to the beginning of the longer string, and process the carry there. Note that you need to allocate a new result anyway, because adding two N
-digit numbers may result in a N+1
-digit number due to the carry.