/*
 * 2進数を10進数に変換するプログラム(負の数は扱えません)
 *
 * ideone上でSIZEの数値変えて試すのなら左上のforkをクリック
 *
 * Author: 俺
 */
#include <stdio.h>
#include <stdlib.h>

/* 2進数の最大桁数(メモリの許す限りいくらでもどうぞ) */
#define SIZE (1000)

void genBits      /* 適当な2進数を生成   */ (int*, const int);
void initDecimal  /* 10進数の初期化      */ (int*, const int);
void bits2decimal /* 2進数を10進数に変換 */ (const int*, const int, int*, const int);
void printBits    /* 2進数を表示         */ (const int*, const int);
void printDecimal /* 10進数を表示        */ (const int*, const int);
void addDecimal   /* 10進数の加算        */ (int*, const int, const int);
void mulDecimal   /* 10進数の乗算        */ (int*, const int, const int);

int main(void) {
	int bits[SIZE];
	int decimal[SIZE];
 
	genBits(bits, SIZE);
	initDecimal(decimal, SIZE);
	
	bits2decimal(bits, SIZE, decimal, SIZE);
	
	printBits(bits, SIZE);
	printDecimal(decimal, SIZE);

	return 0;
}

void genBits(int* bits, const int size) {
	int i;
	for (i = 0; i < size; i++) {
		*(bits++) = rand() % 2;
	}
}

void initDecimal(int* decimal, const int size) {
	int i;
	for (i = 0; i < size; i++) {
		*(decimal++) = 0;
	}
}

void printBits(const int* bits, const int size) {
	char* BIT = "01";
	int f = 0;
	int i;
	printf("BITS:\n");
	bits += size - 1;
	for (i = 0; i < size; i++) {
		if (f == 0) {
			if (*bits == 0) {
				bits--;
				continue;
			}
			f = 1;
		}
		putchar(BIT[*bits]);
		bits--;
	}
	if (f == 0) {
		putchar(BIT[0]);
	}
	putchar('\n');
}

void printDecimal(const int* decimal, const int size) {
	char* NUMBER = "0123456789";
	int f = 0;
	int i;
	printf("DECIMAL:\n");
	decimal += size - 1;
	for (i = 0; i < size; i++) {
		if (f == 0) {
			if (*decimal == 0) {
				decimal--;
				continue;
			}
			f = 1;
		}
		putchar(NUMBER[*decimal]);
		decimal--;
	}
	if (f == 0) {
		putchar(NUMBER[0]);
	}
	putchar('\n');
}

void addDecimal(int* decimal, const int size, const int add) {
	int i;
	(*decimal) += add;
	for (i = 1; i < size; i++) {
		if (*decimal < 10) {
			return;
		}
		(*(decimal + 1)) += *decimal / 10;
		(*decimal) %= 10;
		decimal++;
	}
	(*decimal) %= 10;
}

void mulDecimal(int* decimal, const int size, const int mul) {
	int i;
	int flow = 0;
	for (i = 1; i < size; i++) {
		(*decimal) *= mul;
		(*decimal) += flow;
		if (*decimal > 9) {
			flow = *decimal / 10;
			(*decimal) %= 10;
		} else {
			flow = 0;
		}
		decimal++;
	}
	(*decimal) %= 10;
}

void bits2decimal(const int* bits, const int b_size, int* decimal, const int d_size) {
	int f = 0;
	int i;
	bits += b_size - 1;
	for (i = 0; i < b_size; i++) {
		if (f == 0) {
			if (*bits == 0) {
				bits--;
				continue;
			}
			f = 1;
		}
		mulDecimal(decimal, d_size, 2);
		if (*bits == 1) {
			addDecimal(decimal, d_size, 1);
		}
		bits--;
	}
}


