/* author: Leonardone @ NEETSDKASU */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define BIGNUM_SIZE (60)
#define BIGNUM_FORMAT "%+055.25lf"

typedef char BigNum[BIGNUM_SIZE];

void initBigNumInt(BigNum num, int value);
void initBigNumDbl(BigNum num, double value);
void addBigNum(BigNum res, const BigNum num1, const BigNum num2);
void subBigNum(BigNum res, const BigNum num1, const BigNum num2);
int beginOfBigNum(const BigNum num);
void printBigNum(const BigNum num);
void mulBigNumInt(BigNum res, const BigNum num, int m);

int main(void) {
	BigNum n1, n2, n3, n4, n5, n6;
	
	initBigNumInt(n1, 12345);
	initBigNumDbl(n2, 4.0 * atan(1.0));
	initBigNumInt(n3, 0);
	initBigNumInt(n4, 0);
	initBigNumInt(n5, 0);
	initBigNumInt(n6, 0);
	
	printf(BIGNUM_FORMAT "\n", atof(n1));
	printf(BIGNUM_FORMAT "\n", atof(n2));
	printf(BIGNUM_FORMAT "\n", atof(n3));
	
	addBigNum(n3, n1, n2);
	subBigNum(n4, n1, n2);
	addBigNum(n5, n4, n2);
	mulBigNumInt(n6, n2, 300);

	printf(BIGNUM_FORMAT "\n", atof(n3));
	printf(BIGNUM_FORMAT "\n", atof(n4));
	printf(BIGNUM_FORMAT "\n", atof(n5));
	printf(BIGNUM_FORMAT "\n", atof(n6));
	
	puts("---------");
	
	puts(n1);
	puts(n2);
	puts(n3);
	puts(n4);
	puts(n5);
	puts(n6);
	
	puts("---------");
	
	printBigNum(n1); putchar('\n');
	printBigNum(n2); putchar('\n');
	printBigNum(n3); putchar('\n');
	printBigNum(n4); putchar('\n');
	printBigNum(n5); putchar('\n');
	printBigNum(n6); putchar('\n');
	
	return 0;
}

int beginOfBigNum(const BigNum num) {
	int i;
	int len = strlen(num);
	for (i = 1; i < len; i++) {
		switch (num[i]) {
		case '.':
			return i - 1;
		case '0':
			break;
		default:
			return i;
		} 
	}
	return 0;
}

void printBigNum(const BigNum num) {
	int ps = beginOfBigNum(num);
	if (num[0] == '-') {
		putchar('-');
	}
	printf("%s", num + ps);
}

void initBigNumInt(BigNum num, int value) {
	if (num != NULL) {
		sprintf(num, BIGNUM_FORMAT, (double)value);
	}
}

void initBigNumDbl(BigNum num, double value) {
	if (num != NULL) {
		sprintf(num, BIGNUM_FORMAT, value);
	}
}

void addBigNum(BigNum res, const BigNum num1, const BigNum num2) {
	int len, d1, d2, d3, f;
	if (res == NULL || num1 == NULL || num2 == NULL) {
		return;
	}
	len = strlen(num1) - 1;
	f = 0;
	while (len > 0) {
		d1 = (int)num1[len] - '0';
		d2 = (int)num2[len] - '0';
		d3 = d1 + d2 + f;
		f = d3 / 10;
		res[len] = (char)((d3 % 10) + '0');
		len--;
		if (num1[len] == '.') {
			len--;
		}
	}
}
void subBigNum(BigNum res, const BigNum num1, const BigNum num2) {
	int len, d1, d2, d3, f;
	if (res == NULL || num1 == NULL || num2 == NULL) {
		return;
	}
	len = strlen(num1) - 1;
	f = 0;
	while (len > 0) {
		d1 = (int)num1[len] - '0';
		d2 = (int)num2[len] - '0';
		d3 = d1 - d2 - f;
		if (d3 < 0) {
			d3 += 10;
			f = 1;
		} else {
			f = 0;
		}
		res[len] = (char)(d3 + '0');
		len--;
		if (num1[len] == '.') {
			len--;
		}
	}
}

void mulBigNumInt(BigNum res, const BigNum num, int m) {
	int len, f, d1, d2;
	if (res == NULL || num == NULL || m < 0) {
		return;
	}
	len = strlen(num) - 1;
	f = 0;
	while (len > 0) {
		d1 = (int)num[len] - '0';
		d2 = d1 * m + f;
		f = d2 / 10;
		d2 = d2 % 10;
		res[len] = (char)(d2 + '0');
		len--;
		if (num[len] == '.') {
			len--;
		}
	}
}
