The unavoidable LaTeX3 solution.
The optional argument to \decbin states the number of bits (default 8); \bitcalc should be used in math mode.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% the needed variables
\tl_new:N \l__bee_bindigits_tl
\seq_new:N \l__bee_quotients_seq
\seq_new:N \l__bee_remainders_seq
% the user level macros
\NewDocumentCommand{\decbin}{ O{8} m }
{
\bee_decbin:nn { #1 } { #2 }
}
\NewDocumentCommand{\bitcalc}{m}
{
\bee_bitcalc:n {#1}
}
% the internal functions
\cs_new:Npn \bee_decbin:nn #1 #2
{
\int_compare:nTF { #2 >= 1 \prg_replicate:nn { #1 } { *2 } }
{
BAD! % too few bits
}
{
\bee_print_decbin:nn { #1 } { #2 }
}
}
\cs_new_protected:Npn \bee_print_decbin:nn #1 #2
{
% compute the binary representation
\tl_set:Nx \l__bee_bindigits_tl { \int_to_binary:n { #2 } }
% pad with zeros
\prg_replicate:nn { #1 - \tl_count:N \l__bee_bindigits_tl }
{ \tl_put_left:Nn \l__bee_bindigits_tl { 0 } }
% print the original number
$#2\sb{10}$
% print the boxed binary digits
\tl_map_inline:Nn \l__bee_bindigits_tl { \,\fbox{##1} }
}
\cs_new_protected:Npn \bee_bitcalc:n #1
{
% print the number and start the recursion
#1\sb{10}\to
\seq_clear:N \l__bee_quotients_seq
\seq_clear:N \l__bee_remainders_seq
\bee_bitcalc_aux:n { #1 }
% after the recursion print the binary representation
\int_to_binary:n { #1 }\sb{2}
}
\cs_new_protected:Npn \bee_bitcalc_aux:n #1
{
% if the quotient is nonzero store the current quotient
% and the remainder of the division by 2, then repeat;
% otherwise print the result
\int_compare:nTF { #1 > 0 }
{
\seq_put_right:Nn \l__bee_quotients_seq { 2)\!\underline{\,\, #1 } }
\seq_put_right:Nx \l__bee_remainders_seq { \int_mod:nn { #1 } { 2 } }
\bee_bitcalc_aux:x { \int_div_truncate:nn { #1 } { 2 } }
}
{
\bee_print_computation:
}
}
\cs_generate_variant:Nn \bee_bitcalc_aux:n { x }
\cs_new_protected:Npn \bee_print_computation:
{
\left\{\left.\kern-\nulldelimiterspace
% print the array of quotients
\begin{array}{r}\seq_use:Nnnn \l__bee_quotients_seq { \\ } { \\ } { \\ }\end{array}
\right\uparrow
% print the array of remainders
\begin{array}{c}\seq_use:Nnnn \l__bee_remainders_seq { \\ } { \\ } { \\ }\end{array}
\right\}
}
\ExplSyntaxOff
\begin{document}
\decbin{1}
\decbin{255}
\decbin[16]{256}
\[
\bitcalc{156}
\]
\end{document}

With a straightforward change to a couple of macros we can extend \bitcalc to do the transformation to an (almost) arbitrary base:
\NewDocumentCommand{\bitcalc}{ O{2} m }
{
\bee_bitcalc:nn { #1 } { #2 }
}
\cs_new_protected:Npn \bee_bitcalc:nn #1 #2
{
% print the number and start the recursion
#2\sb{10}\to
\seq_clear:N \l__bee_quotients_seq
\seq_clear:N \l__bee_remainders_seq
\bee_bitcalc_aux:nn { #1 } { #2 }
% after the recursion print the binary representation
\mathrm{ \int_to_base:nn { #2 } { #1 }\sb{ #1 } }
}
\cs_new_protected:Npn \bee_bitcalc_aux:nn #1 #2
{
% if the quotient is nonzero store the current quotient
% and the remainder of the division by #1, then repeat;
% otherwise print the result. Here #1 is the base.
\int_compare:nTF { #2 > 0 }
{
\seq_put_right:Nn \l__bee_quotients_seq { #1)\!\underline{\,\, #2 } }
\seq_put_right:Nx \l__bee_remainders_seq { \int_mod:nn { #2 } { #1 } }
\bee_bitcalc_aux:nx { #1 } { \int_div_truncate:nn { #2 } { #1 } }
}
{
\bee_print_computation:
}
}
\cs_generate_variant:Nn \bee_bitcalc_aux:nn { nx }
No change is needed to \bee_print_computation:. The input
\[
\bitcalc[4]{156}\quad\bitcalc[16]{156}
\]
will generate

The function \int_to_base:nn supports bases from 2 to 36.
Some fixes after a few years
The function \int_to_binary:n has been deprecated. I added a *-version of \bitcalc that adds & just before the arrow, for use in alignments.
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
% the needed variables
\tl_new:N \l__bee_bindigits_tl
\seq_new:N \l__bee_quotients_seq
\seq_new:N \l__bee_remainders_seq
% the user level macros
\NewDocumentCommand{\decbin}{ O{8} m }
{
\bee_decbin:nn { #1 } { #2 }
}
\NewDocumentCommand{\bitcalc}{ s O{2} m }
{
\bee_bitcalc:nnn { #2 } { #3 } { \IfBooleanT{#1}{&} }
}
% the internal functions
\cs_new:Npn \bee_decbin:nn #1 #2
{
\int_compare:nTF { #2 >= 1 \prg_replicate:nn { #1 } { *2 } }
{
BAD! % too few bits
}
{
\bee_print_decbin:nn { #1 } { #2 }
}
}
\cs_new_protected:Npn \bee_print_decbin:nn #1 #2
{
% compute the binary representation
\tl_set:Nx \l__bee_bindigits_tl { \int_to_bin:n { #2 } }
% pad with zeros
\prg_replicate:nn { #1 - \tl_count:N \l__bee_bindigits_tl }
{ \tl_put_left:Nn \l__bee_bindigits_tl { 0 } }
% print the original number
$#2\sb{10}$
% print the boxed binary digits
\tl_map_inline:Nn \l__bee_bindigits_tl { \,\fbox{##1} }
}
\cs_new_protected:Npn \bee_bitcalc:nnn #1 #2 #3
{
% print the number and start the recursion
#2\sb{10}#3\to
\seq_clear:N \l__bee_quotients_seq
\seq_clear:N \l__bee_remainders_seq
\bee_bitcalc_aux:nn { #1 } { #2 }
% after the recursion print the binary representation
\mathrm{ \str_upper_case:f { \int_to_base:nn { #2 } { #1 } }\sb{ #1 } }
}
\cs_new_protected:Npn \bee_bitcalc_aux:nn #1 #2
{
% if the quotient is nonzero store the current quotient
% and the remainder of the division by #1, then repeat;
% otherwise print the result. Here #1 is the base.
\int_compare:nTF { #2 > 0 }
{
\seq_put_right:Nn \l__bee_quotients_seq { #1)\!\underline{\,\, #2 } }
\seq_put_right:Nx \l__bee_remainders_seq { \int_mod:nn { #2 } { #1 } }
\bee_bitcalc_aux:nx { #1 } { \int_div_truncate:nn { #2 } { #1 } }
}
{
\bee_print_computation:
}
}
\cs_generate_variant:Nn \bee_bitcalc_aux:nn { nx }
\cs_new_protected:Npn \bee_print_computation:
{
\left\{
% print the array of quotients
\begin{array}{r}\seq_use:Nn \l__bee_quotients_seq { \\ } \end{array}
\middle\uparrow
% print the array of remainders
\begin{array}{c}\seq_use:Nn \l__bee_remainders_seq { \\ } \end{array}
\right\}
}
\ExplSyntaxOff
\begin{document}
\decbin{1}
\decbin{255}
\decbin[16]{256}
\[
\bitcalc{4096}
\]
\begin{align*}
\bitcalc*{156} & \bitcalc*[3]{156} \\
\bitcalc*[8]{5656} & \bitcalc*[16]{5656}
\end{align*}
\end{document}
