The dcolumn package∗
David Carlisle
2014/10/28
This file is maintained by the LATEX Project team.
Bug reports can be opened (category tools) at
[Link]
Abstract
This package defines a system for defining columns of entries in an array
or tabular which are to be aligned on a ‘decimal point’.
This package defines D to be a column specifier with three arguments.
D{[Link] i}{[Link] i}{hdecimal placesi}
[Link] i should be a single character, this is used as the separator in the .tex
file. Thus it will usually be ‘.’ or ‘,’.
[Link] i is used as the separator in the output, this may be the same as the
first argument, but may be any math-mode expression, such as \cdot. It should be
noted that dcolumn always uses math mode for the digits as well as the separator.
hdecimal placesi should be the maximum number of decimal places in the
column. If this is negative, any number of decimal places can be used in the
column, and all entries will be centred on (the leading edge of) the separator. Note
that this can cause a column to be too wide, compare the first two columns in the
example below. If this argument is positive, the column uses macros equivalent to
\rightdots \endrightdots of [Link], otherwise the macros are essentially
equivalent to \centerdots \endcenterdots.
You may not want to use all three entries in the array or tabular preamble,
so you may define your own preamble specifiers using \newcolumntype.
For example we may say:
\newcolumntype{d}[1]{D{.}{\cdot}{#1}}
d takes a single argument specifying the number of decimal places, and the
.tex file should use ., with · being used in the output.
\newcolumntype{.}{D{.}{.}{-1}}
. specifies a column of entries to be centred on the ..
\newcolumntype{,}{D{,}{,}{2}}
, specifies takes a column of entries with at most two decimal places after a ,.
The following table begins \begin{tabular}{|d{-1}|d{2}|.|,|}
∗ This file has version number v1.06, last revised 2014/10/28.
1
1·2 1·2 1.2 1,2
1·23 1·23 12.5 300,2
1121·2 1121·2 861.20 674,29
184 184 10 69
·4 ·4 ,4
.4
Note that the first column, which had a negative hdecimal placesi argument is
wider than the second column, so that the decimal point appears in the middle
of the column. Also note that this package deals correctly with entries with no
decimal part, no integer part, and blank entries.
If you have table headings (inserted with \multicolumn{1}{c}{..} to over-
ride the D column type) then it may be that neither of the above ‘centred’ or ‘right
aligned’ forms is quite what you want.
head head head wide heading wide heading wide heading
1.2 1.2 1.2 1.2 1.2 1.2
11212.2 11212.2 11212.2 .4 .4 .4
.4 .4 .4
In both of these tables the first column is set with D{.}{.}{-1} to produce
a column centered on the ., and the second column is set with D{.}{.}{1} to
produce a right aligned column.
The centered column produces columns that are wider than necessary to fit in
the numbers under a heading as it has to ensure that the decimal point is centred.
The right aligned column two does not have this drawback, but under a wide
heading a column of small right aligned figures looks a bit odd.
In version v1.03 a third possibility is introduced. The third hdecimal placesi
argument may specify both the number of digits to the left and to the right of the
decimal place. The third column in the first table above is set with D{.}{.}{5.1}
and in the second table, D{.}{.}{1.1}, to specify ‘five places to the left and one
to the right’ and ‘one place to the left and one to the right’ respectively. (You
may use ‘,’ or other tokens, not necessarily ‘.’ in this argument.) The column of
figures is then positioned such that a number with the specified numbers of digits
is centred in the column.
This notation also enables columns that are centred on the mid-point of the
separator, rather than its leading edge; for example D{+}{\,\pm\,}{3,3} will give
nice, symmetric layout of up to three digits on either side of a ± sign.
1 The Macros
1 h*packagei
First we load [Link] if it not already loaded.
2 \RequirePackage{array}
The basic ideas behind these macros are explained in the documentation for
[Link]. However they use three tricks which may be useful in other contexts.
• The separator is surrounded in extra { }, so that it is set with \mathord
spacing, otherwise, for instance a ‘,’ would have extra space after it.
• The separator is not given its special definition by making it active, as this
would not work for an entry such as & .5 &, as the first token of an alignment
2
entry is read before the preamble part, in case it is an \omit, in which case
the preamble is to be omitted. Instead we switch the mathcode to (hex)
8000, which makes the token act as if it were active.
• Although \mathcode‘.="8000 makes . act as if it were active, it is still not
allowed in constructions such as \def.{}, even in math-mode, so we have
to construct an active version of the separator, this is done by making it the
uppercase of ~, and then using the construct
\uppercase{\def~}{hdefinitioni}.
Note that the hdefinitioni is not uppercased, so the definition can refer to
the standard, non-active use of the separator.
\DC@ Set up uppercase tables as required, and then grab the first part of the numerical
argument into \count@.
3 \def\DC@#1#2#3{%
4 \uccode‘\~=‘#1\relax
5 \m@th
6 \afterassignment\DC@x\count@#3\relax{#1}{#2}}
\DC@x If \count@ is negative, centre on the decimal point. If it is positive either #1 will
be empty in which case bad out decimal part to the number of digits specified
by \count@ or (new feature in v1.03) it is none empty in which case \count@
contains the number of digits to the left of the point, and #1 contains a junk token
(probably .) followed by the number of digits to the right of the point. In either
of these latter cases, \DC@right is used.
7 \def\DC@x#1\relax#2#3{%
8 \ifnum\z@>\count@
9 \expandafter\DC@centre
10 \else
11 \expandafter\DC@right
12 \fi
13 {#2}{#3}{#1}}
\DC@centre If centering on the decimal point, just need to box up the two halves.
14 \def\DC@centre#1#2#3{%
15 \let\DC@end\DC@endcentre
16 \uppercase{\def~}{$\egroup\setbox\tw@=\hbox\bgroup${#2}}%
17 \setbox\tw@=\hbox{${\phantom{{#2}}}$}%
18 \setbox\z@=\hbox\bgroup$\mathcode‘#1="8000 }
\DC@endcentre and then pad out the smaller of the two boxes so there is the same amount of stuff
either side of the point.
19 \def\DC@endcentre{$\egroup
20 \ifdim \wd\z@>\wd\tw@
21 \setbox\tw@=\hbox to\wd\z@{\unhbox\tw@\hfill}%
22 \else
23 \setbox\z@=\hbox to\wd\tw@{\hfill\unhbox\z@}\fi
24 \box\z@\box\tw@}
\DC@right This deals with both the cases where a specified number of decimal places is given.
25 \def\DC@right#1#2#3{%
26 \ifx\relax#3\relax
3
If #3 is empty, add \hfill to right align the column, and Just set \DC@rl to begin
a group, so nothing fancy is done with the whole number part.
27 \hfill
28 \let\DC@rl\bgroup
29 \else
Otherwise set \DC@rl so that the whole number part is put in a box \count@
times as wide as a digit. In order to share code with the other branch, then move
#3 (the number of decimal places) into \count@ throwing away the ‘.’ from the
user syntax.
30 \edef\DC@rl{to\the\count@\dimen@ii\bgroup\hss\hfill}%
31 \count@\@gobble#3\relax
32 \fi
33 \let\DC@end\DC@endright
Box 2 contains the decimal part, set to \dimen@ which is calculated below to be
\count@ times the width of a digit, plus the with of the ‘decimal point’.
34 \uppercase{\def~}{$\egroup\setbox\tw@\hbox to\dimen@\bgroup${#2}}%
35 \setbox\z@\hbox{$1$}\dimen@ii\wd\z@
36 \dimen@\count@\dimen@ii
37 \setbox\z@\hbox{${#2}$}\advance\dimen@\wd\z@
38 \setbox\tw@\hbox to\dimen@{}%
Box 0 contains the whole number part, either just at its natural size for right
aligned columns, or set to (the old value of) \count@ times the width of a digit.
\DC@rl defined above determines the two cases.
39 \setbox\z@\hbox\DC@rl$\mathcode‘#1="8000 }
\DC@endright Just finish off the second box, and then put out both boxes.
40 \def\DC@endright{$\hfil\egroup\box\z@\box\tw@}
D The user interface, define the D column to take three arguments. For special
purposes, you may need to directly access \DC@ rather than the D column, eg to
get a bold version you could use
\newcolumntype{E}[3]{>{\boldmath\DC@{#1}{#2}{#3}}c<{\DC@end}}
41 \newcolumntype{D}[3]{>{\DC@{#1}{#2}{#3}}c<{\DC@end}}
42 h/packagei