Skip to content

Instantly share code, notes, and snippets.

@koron
Created October 2, 2011 00:46
Show Gist options
  • Save koron/1256879 to your computer and use it in GitHub Desktop.
Save koron/1256879 to your computer and use it in GitHub Desktop.
bigint arithmetics by string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
static int
digit(char ch)
{
return ch - '0';
}
char*
addsub(char* a, char* b, int subflag)
{
int len_a = strlen(a);
int len_b = strlen(b);
int len_c = MAX(len_a, len_b) + 2;
char *c;
char *p_a, *p_b, *p_c;
int carry;
/* setup output buffer. */
c = (char*)malloc(len_c + 1);
c[len_c] = 0;
/* get tail of each buffer. */
p_a = &a[len_a - 1];
p_b = &b[len_b - 1];
p_c = &c[len_c - 1];
carry = 0;
while (p_c >= c && (p_a >= a || p_b >= b || carry != 0))
{
int n_c, n_a, n_b;
n_a = (p_a >= a) ? digit(*p_a--) : 0;
n_b = (p_b >= b) ? digit(*p_b--) : 0;
if (subflag)
{
n_c = n_a - n_b - carry;
if (n_c < 0)
{
carry = 1;
n_c = 10 + n_c;
/* FIXME: check underflow. */
}
else
{
carry = 0;
/* check last (top) column is '0'. */
if (n_c == 0 && p_a < a && p_b < b)
break;
}
}
else
{
n_c = n_a + n_b + carry;
if (n_c >= 10)
{
carry = 1;
n_c %= 10;
}
else
carry = 0;
}
*p_c-- = n_c + '0';
}
++p_c;
memmove(c, p_c, c + len_c + 1 - p_c);
return c;
}
int
main(int argc, char** argv)
{
if (argc >= 4)
{
int subflag = (argv[2][0] == '-') ? 1 : 0;
char* c = addsub(argv[1], argv[3], subflag);
printf("%s %c %s = %s\n", argv[1], (subflag ? '-' : '+'), argv[3], c);
free(c);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment