Skip to content

Instantly share code, notes, and snippets.

@dce
Last active December 15, 2015 15:49
Show Gist options
  • Save dce/5284790 to your computer and use it in GitHub Desktop.
Save dce/5284790 to your computer and use it in GitHub Desktop.
Add two strings of integers
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define CTOI(c) c - '0'
#define ITOC(i) '0' + i
char *
add(char *n1, char *n2)
{
char *result;
int v1, v2,
l1, l2,
i,
place,
carry,
length;
l1 = strlen(n1);
l2 = strlen(n2);
if (l2 > l1) {
length = l2 + 1;
} else {
length = l1 + 1;
}
result = malloc(length + 1);
result[length + 1] = '\0';
carry = 0;
for (i = 1; i < length; i++) {
v1 = (i > l1) ? 0 : CTOI(n1[l1 - i]);
v2 = (i > l2) ? 0 : CTOI(n2[l2 - i]);
place = v1 + v2 + carry;
result[length - i] = ITOC(place % 10);
carry = place / 10;
}
if (carry) {
result[0] = ITOC(carry);
} else {
strcpy(result, result + 1);
}
return result;
}
int
cmp(char *n1, char *n2) {
int i,
v1, v2,
l1, l2;
l1 = strlen(n1);
l2 = strlen(n2);
if (l1 > l2) {
return 1;
} else if (l1 < l2) {
return -1;
}
for (i = 0; i < l1; i++) {
v1 = CTOI(n1[i]);
v2 = CTOI(n2[i]);
if (v1 > v2) {
return 1;
} else if (v1 < v2) {
return -1;
}
}
return 0;
}
char *
sub(char *n1, char *n2)
{
char *result;
int place,
i,
v1, v2,
l1, l2,
length,
carry;
if (cmp(n1, n2) == -1) {
result = sub(n2, n1);
strcpy(result + 1, result);
result[0] = '-';
return result;
}
l1 = strlen(n1);
l2 = strlen(n2);
if (l2 > l1) {
length = l2;
} else {
length = l1;
}
result = malloc(length);
result[length] = '\0';
carry = 0;
for (i = 1; i <= length; i++) {
v1 = (i > l1) ? 0 : CTOI(n1[l1 - i]);
v2 = (i > l2) ? 0 : CTOI(n2[l2 - i]);
place = v1 - v2 - carry;
if (place < 0) {
place += 10;
carry = 1;
} else {
carry = 0;
}
result[length - i] = ITOC(place);
}
for (i = 0; result[i] == '0'; i++);
if (i < length) {
strcpy(result, result + i);
} else {
strcpy(result, result + i - 1);
}
return result;
}
void
test_add(char *n1, char *n2, char *expected)
{
char *actual = add(n1, n2);
printf("%s + %s: %s\n", n1, n2, actual);
assert(strcmp(expected, actual) == 0);
free(actual);
}
void
test_sub(char *n1, char *n2, char *expected)
{
char *actual = sub(n1, n2);
printf("%s - %s: %s\n", n1, n2, actual);
assert(strcmp(expected, actual) == 0);
free(actual);
}
void
run_add_tests()
{
test_add("0" ,"0" ,"0");
test_add("1" ,"2" ,"3");
test_add("10" ,"20" ,"30");
test_add("17" ,"13" ,"30");
test_add("167" ,"133" ,"300");
test_add("333" ,"667" ,"1000");
test_add("133" ,"10" ,"143");
test_add("1" ,"10000" ,"10001");
test_add("333333333333333333333333333",
"666666666666666666666666667",
"1000000000000000000000000000");
}
void
run_sub_tests()
{
test_sub("0", "0", "0");
test_sub("3", "2", "1");
test_sub("30", "20", "10");
test_sub("30", "15", "15");
test_sub("30", "25", "5");
test_sub("30", "5", "25");
test_sub("300", "299", "1");
test_sub("300", "300", "0");
test_sub("10", "5", "5");
test_sub("5", "10", "-5");
test_sub("1", "1000", "-999");
test_sub("100", "999", "-899");
}
void run_cmp_tests()
{
assert(cmp("1", "1") == 0);
assert(cmp("1", "0") == 1);
assert(cmp("0", "1") == -1);
assert(cmp("30", "15") == 1);
assert(cmp("30", "5") == 1);
}
int
main(int argc, char *argv[])
{
int i;
char *result;
if (argc < 3) {
run_add_tests();
run_sub_tests();
run_cmp_tests();
} else {
result = argv[1];
printf(" %s\n", argv[1]);
for (i = 2; i < argc; i++) {
printf("+ %s\n", argv[i]);
result = add(result, argv[i]);
}
printf(" ---\n %s\n", result);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment