数値Xを2,8,10,16進数で表示する

元の記事とは関係ないけどおまけ

ループその1

それぞれの記数法で各桁を分解することができるでしょうか
わからないときはまずは簡単なところからやりましょう
表示の前にまず桁数を数えるだけやってみましょう

int	log2_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n >>= 1;
	}while( n );
	return	cdigits;
}
int	log8_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n >>= 3;
	}while( n );
	return	cdigits;
}
int	log10_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n /= 10;
	}while( n );
	return	cdigits;
}
int	log16_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n >>= 4;
	}while( n );
	return	cdigits;
}

void	print_log2_i( int	m ){
	int	n = 1;
	while( n < m ){
		debug_printf( "0x%08x%d\n", n-1, log2_i( n-1 ));
		debug_printf( "0x%08x%d\n", n, log2_i( n ));
		debug_printf( "0x%08x%d\n", n+1, log2_i( n+1 ));
		n <<= 1;
	}
}
void	print_log8_i( int	m ){
	int	n = 1;
	while( n < m ){
		debug_printf( "0%o%d\n", n-1, log8_i( n-1 ));
		debug_printf( "0%o%d\n", n, log8_i( n ));
		debug_printf( "0%o%d\n", n*4, log8_i( n*4 ));
		n <<= 3;
	}
}
void	print_log10_i( int	m ){
	int	n = 1;
	while( n < m ){
		debug_printf( "%d%d\n", n-1, log10_i( n-1 ));
		debug_printf( "%d%d\n", n, log10_i( n ));
		debug_printf( "%d%d\n", n*5, log10_i( n*5 ));
		n *= 10;
	}
}
void	print_log16_i( int	m ){
	int	n = 1;
	while( n < m ){
		debug_printf( "0x%08x%d\n", n-1, log16_i( n-1 ));
		debug_printf( "0x%08x%d\n", n, log16_i( n ));
		debug_printf( "0x%08x%d\n", n*8, log16_i( n*8 ));
		n <<= 4;
	}
}

int	main(){
	print_log2_i( 0x10000 );
	print_log8_i( 010000 );
	print_log10_i( 10000 );
	print_log16_i( 0x10000 );
	return	0;
}

ループその2

それぞれの記数法で各桁を分解できるようになったら、それを表示してみましょう
まずは素朴にやってみればいいでしょう

template<typename _value_type> void	reverse_array( _value_type*	pelt, int	celt ){
	int	first = 0;
	int	last = celt-1;
	while( first < last ){
		int	temp = pelt[first];
		pelt[first] = pelt[last];
		pelt[last] = temp;
		++first;
		--last;
	}
}
void	binary_print( int	m ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		digits[cdigits] = '0' + ( n & 1 );
		++cdigits;
		n >>= 1;
	}while( n );
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}
void	octal_print( int	m ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		digits[cdigits] = '0' + ( n & 7 );
		++cdigits;
		n >>= 3;
	}while( n );
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}
void	decimal_print( int	m ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		digits[cdigits] = '0' + ( n % 10 );
		++cdigits;
		n /= 10;
	}while( n );
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}
void	hexadecimal_print( int	m ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		int	c = ( n & 0x0f );
		digits[cdigits] = ( c >= 0x0a ) ? ( 'A' + c - 0x0a ) : ( '0' + c );
		++cdigits;
		n >>= 4;
	}while( n );
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}

int	main(){
	binary_print( 0x1234 );
	octal_print( 01234 );
	decimal_print( 1234 );
	hexadecimal_print( 0x1234 );
	return	0;
}

ループその3

桁数を指定できるようにしてみましょう

template<typename _value_type> void	reverse_array( _value_type*	pelt, int	celt ){
	int	first = 0;
	int	last = celt-1;
	while( first < last ){
		int	temp = pelt[first];
		pelt[first] = pelt[last];
		pelt[last] = temp;
		++first;
		--last;
	}
}
void	binary_print( int	m, int	length ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		digits[cdigits] = '0' + ( n & 1 );
		++cdigits;
		n >>= 1;
	}while( n );
	while( cdigits < length ){
		digits[cdigits] = '0';
		++cdigits;
	}
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}
void	octal_print( int	m, int	length ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		digits[cdigits] = '0' + ( n & 7 );
		++cdigits;
		n >>= 3;
	}while( n );
	while( cdigits < length ){
		digits[cdigits] = '0';
		++cdigits;
	}
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}
void	decimal_print( int	m, int	length ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		digits[cdigits] = '0' + ( n % 10 );
		++cdigits;
		n /= 10;
	}while( n );
	while( cdigits < length ){
		digits[cdigits] = '0';
		++cdigits;
	}
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}
void	hexadecimal_print( int	m, int	length ){
	char	digits[100] = {};
	int	n = m;
	int	cdigits = 0;
	do{
		int	c = ( n & 0x0f );
		digits[cdigits] = ( c >= 0x0a ) ? ( 'A' + c - 0x0a ) : ( '0' + c );
		++cdigits;
		n >>= 4;
	}while( n );
	while( cdigits < length ){
		digits[cdigits] = '0';
		++cdigits;
	}
	digits[cdigits] = 0;
	reverse_array( digits, cdigits );
	debug_printf( digits );
	debug_printf( "\n" );
}

int	main(){
	binary_print( 0x1234, 64 );
	octal_print( 01234, 64 );
	decimal_print( 1234, 64 );
	hexadecimal_print( 0x1234, 64 );
	return	0;
}

ループその4

次にはバッファを使わないようにしてみましょう

int	pow10_i( int	n ){
	int	a = 1;
	for( int	m = 0; m < n; ++m ){
		if( a * 10 < a ){
			a = 0;
			break;
		}
		a *= 10;
	}
	return	a;
}
void	binary_print( int	m, int	length ){
	for( int	n = 0; n < length; ++n ){
		int	l = ( length - n - 1 );
		int	value = 0;
		if(( l >= 0 )&&( l < sizeof( m )*8 )){
			value = (( m >> l ) & 1 );
		}
		char	digit[] = { '0' + value, 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}
void	octal_print( int	m, int	length ){
	for( int	n = 0; n < length; ++n ){
		int	l = ( length - n - 1 ) * 3;
		int	value = 0;
		if(( l >= 0 )&&( l < sizeof( m )*8 )){
			value = (( m >> l ) & 7 );
		}
		char	digit[] = { '0' + value, 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}
void	decimal_print( int	m, int	length ){
	for( int	n = 0; n < length; ++n ){
		int	l = length - n - 1;
		int	a = pow10_i( l );
		int	value = 0;
		if( a ){
			value = ( m / a ) % 10;
		}
		char	digit[] = { '0' + value, 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}
void	hexadecimal_print( int	m, int	length ){
	for( int	n = 0; n < length; ++n ){
		int	l = ( length - n - 1 ) * 4;
		int	value = 0;
		if(( l >= 0 )&&( l < sizeof( m )*8 )){
			value = (( m >> l ) & 0x0f );
		}
		char	digit[] = { ( value >= 0x0a ) ? ( 'A' + value - 0x0a ) : ( '0' + value ), 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}

int	main(){
	binary_print( 0x1234, 64 );
	octal_print( 01234, 64 );
	decimal_print( 1234, 64 );
	hexadecimal_print( 0x1234, 64 );
	return	0;
}

ループその5

さらに事前に桁数をチェックして余計な部分の 0 は先に表示してしまうようにしてみましょう

int	log2_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n >>= 1;
	}while( n );
	return	cdigits;
}
int	log8_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n >>= 3;
	}while( n );
	return	cdigits;
}
int	log10_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n /= 10;
	}while( n );
	return	cdigits;
}
int	log16_i( int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n >>= 4;
	}while( n );
	return	cdigits;
}
int	pow10_i( int	n ){
	int	a = 1;
	for( int	m = 0; m < n; ++m ){
		if( a * 10 < a ){
			a = 0;
			break;
		}
		a *= 10;
	}
	return	a;
}
void	binary_print( int	m, int	max_length ){
	int	length = log2_i( m );
	while( max_length > length ){
		debug_printf( "0" );
		--max_length;
	}
	for( int	n = 0; n < length; ++n ){
		int	value = (( m >> ( length - n - 1 )) & 1 );
		char	digit[] = { '0' + value, 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}
void	octal_print( int	m, int	max_length ){
	int	length = log8_i( m );
	while( max_length > length ){
		debug_printf( "0" );
		--max_length;
	}
	for( int	n = 0; n < length; ++n ){
		int	value = (( m >> (( length - n - 1 ) * 3 )) & 7 );
		char	digit[] = { '0' + value, 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}
void	decimal_print( int	m, int	max_length ){
	int	length = log10_i( m );
	while( max_length > length ){
		debug_printf( "0" );
		--max_length;
	}
	for( int	n = 0; n < length; ++n ){
		int	value = ( m / pow10_i( length - n - 1 )) % 10;
		char	digit[] = { '0' + value, 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}
void	hexadecimal_print( int	m, int	max_length ){
	int	length = log16_i( m );
	while( max_length > length ){
		debug_printf( "0" );
		--max_length;
	}
	for( int	n = 0; n < length; ++n ){
		int	value = (( m >> (( length - n - 1 ) * 4 )) & 0x0f );
		char	digit[] = { ( value >= 0x0a ) ? ( 'A' + value - 0x0a ) : ( '0' + value ), 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}

int	main(){
	binary_print( 0x1234, 64 );
	octal_print( 01234, 64 );
	decimal_print( 1234, 64 );
	hexadecimal_print( 0x1234, 64 );
	return	0;
}

ループその6

それぞれの記数法に特化したコードがあるのは実行効率の点からはいいのですが、ここは一つで全部に対応できるようにしてみるとどうなるかやってみましょう

int	log_i( int	m, int	n ){
	int	cdigits = 0;
	do{
		++cdigits;
		n /= m;
	}while( n );
	return	cdigits;
}
int	pow_i( int	m, int	n ){
	int	a = 1;
	for( int	i = 0; i < n; ++i ){
		if( a * m < a ){
			a = 0;
			break;
		}
		a *= m;
	}
	return	a;
}
void	digits_print( int	m, int	n, int	max_length ){
	int	length = log_i( m, n );
	while( max_length > length ){
		debug_printf( "0" );
		--max_length;
	}
	for( int	i = 0; i < length; ++i ){
		int	value = ( n / pow_i( m, length - i - 1 )) % m;
		char	digit[] = { ( value >= 0x0a ) ? ( 'A' + value - 0x0a ) : ( '0' + value ), 0 };
		debug_printf( digit );
	}
	debug_printf( "\n" );
}

int	main(){
	digits_print( 2, 0x1234, 64 );
	digits_print( 8, 01234, 64 );
	digits_print( 10, 1234, 64 );
	digits_print( 16, 0x1234, 64 );
	return	0;
}

テンプレートその1

さて対象が定数ならテンプレートを使ってコンパイル時に解決することができるということはもうおわかりでしょう
まずは桁数を数えてみましょう

template<int lhs,int rhs> struct less_than_t {
	static const bool	value = ( lhs < rhs );
};
template<int lhs,int rhs> struct less_than_or_equal_to_t {
	static const bool	value = ( lhs <= rhs );
};

template<int n> struct log2_i_helper_t {
	static const int	next = n >> 1;
};
template<int N, int n = N, int cdigits = 0, bool = less_than_t<0,n>::value> struct log2_i_t {
	static const int	value = cdigits;
};
template<int N, int n, int cdigits> struct log2_i_t<N,n,cdigits,true> {
	static const int	value = log2_i_t<N,log2_i_helper_t<n>::next,cdigits+1>::value;
};
template<> struct log2_i_t<0,0,0,false> {
	static const int	value = 1;
};

template<int n> struct log8_i_helper_t {
	static const int	next = n >> 3;
};
template<int N, int n = N, int cdigits = 0, bool = less_than_t<0,n>::value> struct log8_i_t {
	static const int	value = cdigits;
};
template<int N, int n, int cdigits> struct log8_i_t<N,n,cdigits,true> {
	static const int	value = log8_i_t<N,log8_i_helper_t<n>::next,cdigits+1>::value;
};
template<> struct log8_i_t<0,0,0,false> {
	static const int	value = 1;
};

template<int n> struct log10_i_helper_t {
	static const int	next = n / 10;
};
template<int N, int n = N, int cdigits = 0, bool = less_than_t<0,n>::value> struct log10_i_t {
	static const int	value = cdigits;
};
template<int N, int n, int cdigits> struct log10_i_t<N,n,cdigits,true> {
	static const int	value = log10_i_t<N,log10_i_helper_t<n>::next,cdigits+1>::value;
};
template<> struct log10_i_t<0,0,0,false> {
	static const int	value = 1;
};

template<int n> struct log16_i_helper_t {
	static const int	next = n >> 4;
};
template<int N, int n = N, int cdigits = 0, bool = less_than_t<0,n>::value> struct log16_i_t {
	static const int	value = cdigits;
};
template<int N, int n, int cdigits> struct log16_i_t<N,n,cdigits,true> {
	static const int	value = log16_i_t<N,log16_i_helper_t<n>::next,cdigits+1>::value;
};
template<> struct log16_i_t<0,0,0,false> {
	static const int	value = 1;
};

template<int max_value, int n = 1, bool = less_than_or_equal_to_t<n,max_value>::value> struct print_log2_i_helper_t {
	static void	print(){
	}
};
template<int max_value, int n> struct print_log2_i_helper_t<max_value,n,true> {
	static void	print(){
		debug_printf( "0x%08x%d\n", n-1, log2_i_t<n-1>::value );
		debug_printf( "0x%08x%d\n", n, log2_i_t<n>::value );
		debug_printf( "0x%08x%d\n", n+1, log2_i_t<n+1>::value );
		print_log2_i_helper_t<max_value,(!n?1:(n*2))>::print();
	}
};
template<int max_value, int n = 1, bool = less_than_or_equal_to_t<n,max_value>::value> struct print_log8_i_helper_t {
	static void	print(){
	}
};
template<int max_value, int n> struct print_log8_i_helper_t<max_value,n,true> {
	static void	print(){
		debug_printf( "0%o%d\n", n-1, log8_i_t<n-1>::value );
		debug_printf( "0%o%d\n", n, log8_i_t<n>::value );
		debug_printf( "0%o%d\n", n*4, log8_i_t<n*4>::value );
		print_log8_i_helper_t<max_value,(!n?1:(n*8))>::print();
	}
};
template<int max_value, int n = 1, bool = less_than_or_equal_to_t<n,max_value>::value> struct print_log10_i_helper_t {
	static void	print(){
	}
};
template<int max_value, int n> struct print_log10_i_helper_t<max_value,n,true> {
	static void	print(){
		debug_printf( "%d%d\n", n-1, log10_i_t<n-1>::value );
		debug_printf( "%d%d\n", n, log10_i_t<n>::value );
		debug_printf( "%d%d\n", n*5, log10_i_t<n*5>::value );
		print_log10_i_helper_t<max_value,(!n?1:(n*10))>::print();
	}
};
template<int max_value, int n = 1, bool = less_than_or_equal_to_t<n,max_value>::value> struct print_log16_i_helper_t {
	static void	print(){
	}
};
template<int max_value, int n> struct print_log16_i_helper_t<max_value,n,true> {
	static void	print(){
		debug_printf( "0x%08x%d\n", n-1, log16_i_t<n-1>::value );
		debug_printf( "0x%08x%d\n", n, log16_i_t<n>::value );
		debug_printf( "0x%08x%d\n", n*8, log16_i_t<n*8>::value );
		print_log16_i_helper_t<max_value,(!n?1:(n*16))>::print();
	}
};

int	main(){
	print_log2_i_helper_t<0x10000>::print();
	print_log8_i_helper_t<010000>::print();
	print_log10_i_helper_t<10000>::print();
	print_log16_i_helper_t<0x10000>::print();
	return	0;
}

テンプレートその2

桁数を数えることができるようになったらでは表示をしてみましょう

template<int lhs, int rhs> struct less_than_t {
	static const bool	value = ( lhs < rhs );
};

template<int M,int _value = 1,bool = less_than_t<M,0>::value> struct pow10_i_t {
	static const int	value = _value;
};
template<int M,int _value> struct pow10_i_t<M,_value,false> {
	static const int	value = 10 * pow10_i_t<M-1,_value*10>::value;
};
template<int _value> struct pow10_i_t<0,_value,false> {
	static const int	value = 1;
};
template<> struct pow10_i_t<0,1,false> {
	static const int	value = 1;
};

template<int n> struct log10_i_helper_t {
	static const int	next = n / 10;
};
template<int N, int n = N, int cdigits = 0, bool = less_than_t<0,n>::value> struct log10_i_t {
	static const int	value = cdigits;
};
template<int N, int n, int cdigits> struct log10_i_t<N,n,cdigits,true> {
	static const int	value = log10_i_t<N,log10_i_helper_t<n>::next,cdigits+1>::value;
};
template<> struct log10_i_t<0,0,0,false> {
	static const int	value = 1;
};

template<int N,int n = 0, bool = less_than_t<n,0>::value,bool = less_than_t<n,sizeof( N )*8>::value> struct binary_digit_t {
	static const int	value = ( N >> n ) & 1;
};
template<int N,int n, bool is_negative> struct binary_digit_t<N,n,is_negative,false> {
	static const int	value = 0;
};
template<int N,int n,bool is_end> struct binary_digit_t<N,n,true,is_end> {
	static const int	value = 0;
};

template<int N,int n = 0, bool = less_than_t<n*3,0>::value,bool = less_than_t<n*3,sizeof( N )*8>::value> struct octal_digit_t {
	static const int	value = ( N >> (n*3)) & 0x07;
};
template<int N,int n, bool is_negative> struct octal_digit_t<N,n,is_negative,false> {
	static const int	value = 0;
};
template<int N,int n,bool is_end> struct octal_digit_t<N,n,true,is_end> {
	static const int	value = 0;
};

template<int N,int n = 0, bool = less_than_t<n,0>::value,bool = less_than_t<n,log10_i_t<N>::value>::value> struct decimal_digit_t {
	static const int	value = ( N / pow10_i_t<n>::value ) % 10;
};
template<int N,int n, bool is_negative> struct decimal_digit_t<N,n,is_negative,false> {
	static const int	value = 0;
};
template<int N,int n,bool is_end> struct decimal_digit_t<N,n,true,is_end> {
	static const int	value = 0;
};

template<int N,int n = 0, bool = less_than_t<n*4,0>::value,bool = less_than_t<n*4,sizeof( N )*8>::value> struct hexadecimal_digit_t {
	static const int	value = ( N >> (n*4)) & 0x0f;
};
template<int N,int n, bool is_negative> struct hexadecimal_digit_t<N,n,is_negative,false> {
	static const int	value = 0;
};
template<int N,int n,bool is_end> struct hexadecimal_digit_t<N,n,true,is_end> {
	static const int	value = 0;
};

template<int N,int length,int n = 0,int = binary_digit_t<N,length-n-1>::value,bool = less_than_t<n,length>::value> struct binary_print_t {
	static void	print(){
		debug_printf( "\n" );
	}
};
template<int N,int length,int n, int value> struct binary_print_t<N,length,n,value,true> {
	static void	print(){
		const char	s[] = { '0' + value, 0 };
		debug_printf( s );
		binary_print_t<N,length,n+1>::print();
	}
};

template<int N,int length,int n = 0,int = octal_digit_t<N,length-n-1>::value,bool = less_than_t<n,length>::value> struct octal_print_t {
	static void	print(){
		debug_printf( "\n" );
	}
};
template<int N,int length,int n, int value> struct octal_print_t<N,length,n,value,true> {
	static void	print(){
		const char	s[] = { '0' + value, 0 };
		debug_printf( s );
		octal_print_t<N,length,n+1>::print();
	}
};

template<int N,int length,int n = 0,int = decimal_digit_t<N,length-n-1>::value,bool = less_than_t<n,length>::value> struct decimal_print_t {
	static void	print(){
		debug_printf( "\n" );
	}
};
template<int N,int length,int n, int value> struct decimal_print_t<N,length,n,value,true> {
	static void	print(){
		const char	s[] = { '0' + value, 0 };
		debug_printf( s );
		decimal_print_t<N,length,n+1>::print();
	}
};

template<int N,int length,int n = 0,int = hexadecimal_digit_t<N,length-n-1>::value,bool = less_than_t<n,length>::value> struct hexadecimal_print_t {
	static void	print(){
		debug_printf( "\n" );
	}
};
template<int N,int length,int n, int value> struct hexadecimal_print_t<N,length,n,value,true> {
	static void	print(){
		const char	s[] = { ( value >= 0x0a ) ? ( 'A' + value - 0x0a ) : ( '0' + value ), 0 };
		debug_printf( s );
		hexadecimal_print_t<N,length,n+1>::print();
	}
};
int	main(){
	binary_print_t<0x1234,64>::print();
	octal_print_t<01234,64>::print();
	decimal_print_t<1234,64>::print();
	hexadecimal_print_t<0x1234,64>::print();
	return	0;
}

テンプレートその3

共通のコードをまとめると

template<int lhs, int rhs> struct less_than_t {
	static const bool	value = ( lhs < rhs );
};

template<int N,int M,int _value = 1,bool = less_than_t<M,0>::value> struct pow_i_t {
	static const int	value = _value;
};
template<int N,int M,int _value> struct pow_i_t<N,M,_value,false> {
	static const int	value = N * pow_i_t<N,M-1,_value*N>::value;
};
template<int N,int _value> struct pow_i_t<N,0,_value,false> {
	static const int	value = 1;
};
template<int M,int _value,bool is_end> struct pow_i_t<0,M,_value,is_end> {
	static const int	value = 0;
};
template<> struct pow_i_t<0,0,1,false> {
	static const int	value = 1;
};

template<int N,int M> struct log_i_helper_t {
	static const int	next = M / N;
};
template<int M> struct log_i_helper_t<0,M> {
	static const int	next = 0;
};
template<int N,int M,int m = M, int cdigits = 0, bool = less_than_t<0,m>::value> struct log_i_t {
	static const int	value = cdigits;
};
template<int N,int M,int m, int cdigits> struct log_i_t<N,M,m,cdigits,true> {
	static const int	value = log_i_t<N,M,log_i_helper_t<N,m>::next,cdigits+1>::value;
};
template<int N> struct log_i_t<N,0,0,0,false> {
	static const int	value = 1;
};

template<int N,int M,int m, bool = less_than_t<m,0>::value,bool = less_than_t<m,log_i_t<N,M>::value>::value> struct digit_t {
	static const int	value = ( M / pow_i_t<N,m>::value ) % N;
};
template<int N,int M,int m, bool is_negative> struct digit_t<N,M,m,is_negative,false> {
	static const int	value = 0;
};
template<int N,int M,int m,bool is_end> struct digit_t<N,M,m,true,is_end> {
	static const int	value = 0;
};

template<int n, bool = less_than_t<n,0x0a>::value> struct digit_char_t {
	static const char	value = '0' + n;
};
template<int n> struct digit_char_t<n,false> {
	static const char	value = 'A' + n - 0x0a;
};
template<int N,int M,int length,int m = 0,int = digit_t<N,M,length-m-1>::value,bool = less_than_t<m,length>::value> struct digits_print_t {
	static void	print(){
		debug_printf( "\n" );
	}
};
template<int N,int M,int length,int m, int value> struct digits_print_t<N,M,length,m,value,true> {
	static void	print(){
		const char	s[] = { digit_char_t<value>::value, 0 };
		debug_printf( s );
		digits_print_t<N,M,length,m+1>::print();
	}
};

int	main(){
	digits_print_t<2,0x1234,64>::print();
	digits_print_t<8,01234,64>::print();
	digits_print_t<10,1234,64>::print();
	digits_print_t<16,0x1234,64>::print();
	return	0;
}