# How to align numbers in a table with different character width?

I try to align some HEX numbers in the style of 0x1FFFF and 0x00001 in a table. They have to be aligned to the right, but I also want them to have the same witdh per character, despite an F beeing a lot wider than a 0 or any other number. Otherwise it looks really silly when the 0x in the beginning do not aling with each other...

This code here

\begin{table}
\begin{center}
\begin{tabular}{@{}lr@{}}
\toprule
\textbf{DEC} \hspace{10mm}      & \textbf{HEX} \\
\midrule
1           & 0x00001  \\
2           & 0x00002  \\
100         & 0x00064  \\
131.071     & 0x1FFFF  \\
262143      & 0x3FFFF  \\
\bottomrule
\end{tabular}
\end{center}
\end{table}


creates this table

Is there some way to align the numbers on the right properly, so that I does not look like different amount of digits?

• Welcome to TeX.SX! You probably need a monospaced font... Aug 9 '17 at 8:22
• GOV.UK has a separate font which is identical to their main font, but with equally spaced characters. The font is specifically for tabular data like this.
– ESR
Aug 10 '17 at 5:04

Same width per character means that you need a font which matches this requirement. Usually that's a mono-spaced font you can access with \texttt.

\documentclass{article}
\usepackage{booktabs}
\usepackage{array}
\begin{document}
\begin{table}
\centering
\begin{tabular}{@{}l>{\ttfamily}r@{}}
\toprule
\textbf{DEC} \hspace{10mm}      & \textbf{HEX} \\
\midrule
1           & 0x00001  \\
2           & 0x00002  \\
100         & 0x00064  \\
131.071     & 0x1FFFF  \\
262143      & 0x3FFFF  \\
\bottomrule
\end{tabular}
\end{table}
\end{document}

• Ah, that seems a bit curious, when one column is in a different style, but it works. Thanks ;) Aug 9 '17 at 8:36
• is the \arraybackslash in the socund column definition really needed? also instead of \begin{center} ... \end{center} is better \centering and all columns to use the same font family :) Aug 9 '17 at 9:00
• @Zarko Well, no. And you're right. I'll update. Aug 9 '17 at 9:01

Instead of a real monospaced font you could also fake it:

\documentclass{article}
\usepackage{booktabs}

\newcommand*{\fakemonochar}[1]{\makebox[.6em][c]{#1}}
\makeatletter
\newcommand*{\fakemonotext}[1]{%
\@fakemonotext#1\\%
}
\newcommand*{\@fakemonotext}[1]{%
\ifx #1\\\else\fakemonochar{#1}\expandafter\@fakemonotext\fi
}
\makeatother

\begin{document}

\begin{tabular}{@{}lrr@{}}
\toprule
\textbf{DEC} & \textbf{HEX} (faked) & \textbf{HEX} (mono)\\
\midrule
1           & \fakemonotext{0x00001} & \texttt{0x00001} \\
2           & \fakemonotext{0x00002} & \texttt{0x00002} \\
100         & \fakemonotext{0x00064} & \texttt{0x00064} \\
131.071     & \fakemonotext{0x1FFFF} & \texttt{0x1FFFF} \\
262143      & \fakemonotext{0x3FFFF} & \texttt{0x3FFFF} \\
\bottomrule
\end{tabular}
\end{document}


• Very nice idea. Aug 9 '17 at 9:03
• @TeXnician I do not like the faked monospace. The letters are OK, but the digits … ugly. If I could, I would down-vote this answer. ;-) Aug 9 '17 at 9:21
• I do not like the appearance either, but I like the idea to fake mono with boxes. Aug 9 '17 at 9:23
• @TeXnician You could also use \newcommand*{\fakemonotext}[1]{\makebox[4em][s]{\fontdimen4\font=\fontdimen2\font #1}} and \fakemonotext{0x0 0 0 0 1}. This could even be used with a p-column with initial \fontdimen change. Then you would not need \fakemonotext. But the input in both cases have to be with spaces to have inter word space between the hex digits. Aug 9 '17 at 9:34

You can let TeX do the computations!

\documentclass{article}

\usepackage{xparse,booktabs,siunitx}

\ExplSyntaxOn
\NewDocumentCommand{\hexnum}{ O{ \l_hexnum_pad_int } m }
{
\hexnum_print:nn { #1 } { #2 }
}
\NewDocumentCommand{\hexrow}{ O{ \l_hexnum_pad_int } m }
{
\num{#2} & \hexnum_print:nn { #1 } { #2 }
}
{
}

\cs_new_protected:Nn \hexnum_print:nn
{
\texttt{ 0x \hexnum_pad:nf { #1 } { \int_to_Hex:n { #2 } } }
}

{
\int_compare:nF { #1 == 0 }
{
\prg_replicate:nn { #1 - \tl_count:n { #2 } } { 0 }
}
#2
}

\ExplSyntaxOff

\begin{document}

Stand alone: \hexnum[0]{35671} or \hexnum{35671}

\bigskip

\begin{tabular}{ l r }
\toprule
{DEC} & \multicolumn{1}{c}{HEX} \\
\midrule
\hexrow{1} \\
\hexrow{2} \\
\hexrow{100} \\
\hexrow{131071} \\
\hexrow{262143} \\
\bottomrule
\end{tabular}
%
%
\begin{tabular}{ l r }
\toprule
{DEC} & \multicolumn{1}{c}{HEX} \\
\midrule
\hexrow[1]{1} \\
\hexrow{2} \\
\hexrow{100} \\
\hexrow{131071} \\
\hexrow{262143} \\
\bottomrule
\end{tabular}

\end{document}


The padding is done to \l_hexnum_pad_int digits, which you can set either with \sethexnumpad or with the optional argument to \hexnum (or \hexrow` that's a wrapper to it). If the value is set to 0, no padding is done.