[Tex/LaTex] siunitx error: Invalid numerical input

siunitxtables

I use siunitx package to display intervals in tabular, according to this answer. But I use parenthesis instead of square bracket. This is a MWE:

%!TeX program = xelatex
%!TeX encoding = UTF-8
\documentclass{article}

\usepackage{siunitx}
\usepackage{pdflscape}
\usepackage{booktabs}

\begin{document}
\begin{landscape}
\begin{table}
\begin{tabular}{
        l*{3}{
        S[table-format=1.3]@{\hspace{0.5em}}
        >{{(}}
        S[table-format=1.3,table-space-text-pre={(}]
        @{,\,}
        S[table-format=1.3,table-space-text-post={)}]
        <{{)}}@{\hspace{2em}}
        }
        S[table-format=1.3]@{\hspace{0.5em}}
        >{{(}}
        S[table-format=1.3,table-space-text-pre={(}]
        @{,\,}
        S[table-format=1.3,table-space-text-post={)}]
        <{{)}}
    }

    \toprule

    {} & \multicolumn{3}{c@{\hspace{2em}}}{$\mathit{Exp}(\lambda)$} & \multicolumn{3}{c@{\hspace{2.5em}}}{$G(2,\lambda)$} & \multicolumn{3}{c@{\hspace{2.5em}}}{$G(3,\lambda)$} & \multicolumn{3}{@{}c@{\hspace{0.5em}}}{$N^+(\mu,\omega^2)$} \\

    \midrule

    $\alpha_0$ & 4.239 & 4.150 & 4.330   & 4.315 & 4.225 & 4.404   & 4.371 & 4.281 & 4.459   & 4.273 & 4.183 & 4.365\cr
    $\alpha_1$ & 0.024 & 0.024 & 0.025   & 0.024 & 0.024 & 0.025   & 0.024 & 0.024 & 0.025   & 0.024 & 0.024 & 0.025\cr
    $\beta_1$ & 0.054 & 0.049 & 0.060   & 0.051 & 0.045 & 0.056   & 0.049 & 0.043 & 0.054   & 0.051 & 0.046 & 0.057\cr
    $\beta_2$ & 0.755 & 0.749 & 0.761   & 0.761 & 0.755 & 0.767   & 0.765 & 0.758 & 0.771   & 0.761 & 0.755 & 0.767\cr
    $\beta_3$ & 0.109 & 0.102 & 0.116   & 0.106 & 0.099 & 0.113   & 0.105 & 0.098 & 0.112      & 0.106 & 0.099 & 0.113\cr
    $\sigma^2$ & 0.032 & 0.031 & 0.033   & 0.031 & 0.030 & 0.032   & 0.030 & 0.030 & 0.031   & 0.031 & 0.030 & 0.032\cr
    $\lambda$ & 1.426 & 1.352 & 1.502   & 2.468 & 2.356 & 2.588   & 3.383 & 3.240 & 3.531     & \multicolumn{3}{@{}c@{\hspace{0.5em}}}{--}\cr
    $\mu$ & \multicolumn{3}{c@{\hspace{2em}}}{--} & \multicolumn{3}{c@{\hspace{2.5em}}}{--} & \multicolumn{3}{c@{\hspace{2.5em}}}{--}    & 0.286 & 0.243 & 0.324\cr
    $\omega^2$ & \multicolumn{3}{c@{\hspace{2em}}}{--} & \multicolumn{3}{c@{\hspace{2.5em}}}{--} & \multicolumn{3}{c@{\hspace{2.5em}}}{--}   & 0.440 & 0.397 & 0.485\cr
    DIC & \multicolumn{3}{c@{\hspace{2em}}}{$-$9687.5} & \multicolumn{3}{c@{\hspace{2.5em}}}{$-$10274.1} & \multicolumn{3}{c@{\hspace{2.5em}}}{$-$10592.1} & \multicolumn{3}{@{}c@{\hspace{0.5em}}}{$-$10173.7}\cr

    \bottomrule
\end{tabular}
\end{table}
\end{landscape}
\end{document}

Actually, it works well on TeX Live 2017 (the version of siunitx is v2.7g). But when I compile it on TeX Live 2019 (the version of siunitx is v2.7s), an error arises, which says invalid numerical input '(4.150'. I'm confused. However, if I use square brackets, the error disappears. So I think the problem is that the parenthese are always considered as opening and closing symbols used for uncertainty input, when only left parenthesis used, the siunitx package decides it is an invalid numerical input. Therefore, I change input-open-uncertainty to [ and input-close-uncertainty to ]

\sisetup{input-open-uncertainty=[,input-close-uncertainty=]}

And it works! So I want to know why a single parenthesis can not be used with a number even if table-space-text-pre is specified. Why does this problem happen in the newer version of siunitx package?

Best Answer

You correctly surmised that the opening parenthesis is always treated as marking the start of the uncertainty. This is necessary for siunitx to be able to reliably parse numbers. The option table-space-text-pre does not change this; it only adds the width of its value (( in this case) to the column, the actual token (() is not treated any differently because of this.

You can still achieve your goal without redefining the uncertainty input by hiding the parentheses from the parser. This can be done by putting them inside a group (between { and }). It looks like you already tried this in >{{(}}, but the error message tells you that this group is not there any more when the siunitx parser reads the parenthesis. How can this be?

When TeX consumes the argument of a macro, it strips it of one layer of braces (if present). This means that sometimes, depending on the implementation of the macros you are using, some of the braces you type disappear before they reach the part of the machine they were meant for.

There are two ways of dealing with this.

  • You could add more braces. In your case, one additional layer is enough: >{{{(}}}
  • You can hide your braces from TeX by putting them inside a macro. Define a macro \newcommand*\foo{{(}} and use it like >{\foo}. Now, when this argument is handed through the different macros implementing the table, \foo is still unexpanded. It only gets expanded once the siunitx parser tries to make sense of its input and then it finds {(}, as desired. In general, this approach is much safer and easier than the first one since you don't have to first find out how many layers of braces you need and your code does not break when this number changes.

As to why this does not occur in older versions of siunitx I can only guess. To me, it looks like either a bug in the old versions or a new feature in the new ones. (Being able to add parts of the number before parsing using > and < is definitely a feature, I would say.)