34

Is it possible to have automatic rounding of numbers in a table?

Say that I have this, made in the usual way with a tabular environment:

pi  | 3.14592654
e   | 2.7182818284
phi | 1.6180339887

Can I control how many significant digits are shown without truncating the numbers manually myself?

So for example, if I need four significant digits, the numbers should appear as

pi  | 3.1459
e   | 2.7183
phi | 1.6180

Bonus points for actually rounding the numbers according to the usual rules without simply truncating them.


I understand this is probably non-trivial, so here's a relaxed version that will also work in my circumstances (all numbers have one and the same precision and character count):

(How) Can I control how many characters are rendered in a column of a table?

So if I define the text in the columns as:

\begin{tabular} % some black magic column definition
   text & alongword\\
   text & anotherlongword\\
   text & morelongwords\\
\end{tabular}

I'd like to get something like:

text along
text anoth
text morel

I know there are non-TeX ways to do this, and I will probably resolve to writing a script if all else fails, but I'm curious whether there's a way to do it solely with TeX & friends.

Mico
  • 506,678

5 Answers5

31

For numbers:

There are some packages, like siunitx and math engine of tikz (especially in pgfplotstable), which can used to format numbers in LaTeX. numprint may be the simplest one, and can be easily used in tabulars.

numprint package privides n and N column types for numbers in tabular, and \nprounddigits for set the precision. An example:

% \usepackage{numprint} in preamble
\npdecimalsign{.}
\nprounddigits{2}
\begin{tabular}{c|n{5}{2}|}
foo & 12345 \\
bar & 12345.12345 \\
baz & 0.00012345 \\
\end{tabular}
\npnoround

Please read the manual for more options.


For common characters, @TH has showed some TeX trick. However, you can use xstring package or something else to do the dirty work. I don't know how to get full control in tabular, so here is just a incomplete solution, a mix of xtring and primitive TeX:

\halign{\StrLeft{#}{4} \cr
 abc \cr
 abcde \cr
 abcdefg \cr
}

Any further suggestions are welcome.

David Carlisle
  • 757,742
Leo Liu
  • 77,365
  • numprint is very nice! It has a lot other useful stuff that will certainly come in handy. Thanks! – Martin Tapankov Jan 17 '11 at 12:37
  • How can I keep the header row text centered while using this package??? – Daniel Aug 02 '13 at 21:08
  • @Daniel: For siunitx, use {header}. For other simpler packages, use \multicolumn{1}{c}{...} – Leo Liu Aug 03 '13 at 05:07
  • Can I specify a different amount of rounding for each column? I can't see this in the manual. – Aaron McDaid May 31 '15 at 14:34
  • Is it possible to format a number after rounding to have a leading decimal point for values less than 1.0 i.e. I would like to see .005 instead of 0.005 ?? – Sebastian Widz Mar 14 '17 at 22:06
  • numprint makes it non-trivial to align the numbers in the columns of the table. The way I see it siunitx works in a less intrusive way (no preamble declarations other than the package declaration) and the number alignment just works without tweaks, as in the solution provided by @Mico below or in this other answer. – Pablo Adames May 21 '20 at 01:08
11

Here's one way to do it that's a bit of a hack (which is to say that Leo Liu's answer is far better, it's just fun to try to do this yourself sometimes):

\documentclass{article}
\usepackage{array}
\usepackage{fp}
\newcolumntype{T}{>{\trunc}r}
\def\trunc\ignorespaces#1\\{%
        \FPset\a{#1}
        \FPround\a\a4
        \a
        \\
}
\begin{document}
\begin{tabular}{>{$}l<{$}T}
\pi  & 3.14159265358979323848\\
e    & 2.71828182845904523536\\
\phi & 1.61803399\\
x    & 37\\
\end{tabular}
\end{document}

alt text

The T specifier has to be at the end of the row and it must be terminated with a \\. You could write an analogous one that works in the middle of the row by delimiting it with & rather than \\.

The original version differed only in the definition of \trunc.

\def\trunc#1.#2#3#4#5#6\\{#1.#2#3#4#5\\}
Werner
  • 603,163
TH.
  • 62,639
8

Here are two solutions to the automatic rounding problem for numbers.

  • The first employs the S column type of the siunitx package, with the options round-mode=places and round-precision=<n>, where <n> is the number of digits to be shown after the decimal marker. (The option table-format=1.<n> is optional but is useful if you wish to typeset the numeric column tightly.)

  • The second solution uses Lua's powerful string.format function and thus requires LuaLaTeX. The utility LaTeX macro \myprint employs Lua's string.format function. Observe that the argument of \myprint is expandable; thus, one could replace \myprint{3.1415926536} with \myprint{math.pi}. The only real requirement is that the argument of \myprint must evaluate to a number.

In the following table, the precision is set to 4 for the S-based solution and 5 for the LuaLaTeX-based solution.

enter image description here

\documentclass{article}
\usepackage[group-decimal-digits=false]{siunitx} % for "S" column type
\usepackage{luacode} % for \luaexec macro
% create a utility LaTeX macro:
\newcommand\myprint[1]{\luaexec{% 
   tex.sprint ( string.format ( "\%.5f" , #1 )  ) }}
\begin{document}
\begin{table}
\[
\begin{array}{ l 
               S[table-format=1.4,round-mode=places,round-precision=4] 
               l }
\pi        & 3.1415926536 & \myprint{3.1415926536}  \\
\mathrm{e} & 2.7182818285 & \myprint{2.7182818285}  \\
\phi       & 1.6180339887 & \myprint{1.6180339887}
\end{array}
\]
\end{table}
\end{document}
Mico
  • 506,678
8
\documentclass{article}
\usepackage{array,xstring}

\newcolumntype{N}{>{\GobbleA} r<{;;} }
\def\GobbleA\ignorespaces#1.#2;;{%
  \ignorespaces#1.\StrLeft{#2}{4}}

\newcolumntype{S}{>{\GobbleB} l }
\def\GobbleB#1#2\\{\StrLeft{#2}{4}\\}

\begin{document}
\begin{tabular}{>{$}l<{$} N S}
\pi  & 3.14159265358979323848 & delicious \\
e    & 2.71828182845904523536 & foo \\
\phi & 1.61803399             & extraordinarylong \\
x    & 37.11111               & { } \\
\end{tabular}

\end{document}

alt text

Werner
  • 603,163
  • I can't run this solution but it is particularly suitable for my problem because I see it should work using comma as separator instead of dot. However, I am getting this message everytime:
    ! Use of \@@array doesn't match its definition.
    \new@ifnextchar ...served@d = #1\def \reserved@a {
                                                  #2}\def \reserved@b {#3}\f...
    l.207 Lys1   &
               10.8  &    {} &  11.4267 \\
    ?
    
    – jasikevicius23 May 21 '15 at 21:34
  • complete example, please –  May 22 '15 at 04:44
  • @jasikevicius23: have you seen \npdecimalsign{.} above? The manual says: \npdecimalsign{\ensuremath{\cdot}}\npthousandsep{,}\npproductsign{*}% \numprint{-123456}; \numprint{3,1415927e-3.2} leads to “ −123,456; 3 $\cdot$ 141,592,7*10... – serv-inc Aug 28 '16 at 07:54
2

A knitr-xtable approach, making a .Rnw file:

mwe

\documentclass{article}
\usepackage{booktabs}  
\renewcommand\belowcaptionskip{1ex}
\begin{document}
<<echo=F,results="asis">>=
library(xtable)
x <- data.frame(Symbol=c("$\\pi$","$e$","$\\phi$","$x$"),
Value=c(3.14159265358979323848, 2.71828182845904523536, 
1.61803399, 37))
print(xtable(x,caption="Irrational numbers",align="ccr", 
digits=c(0,0,4)), 
      include.rownames=F, include.colnames=T, 
      booktabs=T, caption.placement="top",
      sanitize.text.function=function(x){x})
@
\end{document}

The conversion .Rnw.tex.pdf can be done easily with Rstudio.

A more manual option is run only the R code (lines 6-14 of the MWE) and copy & paste the LaTeX ouput in a true LaTeX document, that is in this case will be be:

% latex table generated in R 3.3.1 by xtable 1.8-2 package
% Sat Sep 30 00:38:28 2017
\begin{table}[ht]
\centering
\caption{Irrational numbers}
\begin{tabular}{cr}
\toprule
Symbol & Value \\
\midrule
$\pi$ & 3.1416 \\
$e$ & 2.7183 \\
$\phi$ & 1.6180 \\
$x$ & 37.0000 \\
\bottomrule
\end{tabular}
\end{table}
Fran
  • 80,769