[Tex/LaTex] Scientific Notation Only For Large Numbers — with uncertainty

expl3siunitx

I've been using Betohaku and Bruno Le Floch's answer to Scientific Notation Only For Large Numbers to turn scientific notation of as follows:

\documentclass{standalone}
\RequirePackage[
    per-mode=reciprocal,
    scientific-notation=true,
    retain-explicit-plus,
    table-space-text-post=\textsuperscript{~a},
    table-align-text-post=true,
    table-align-exponent,
    table-align-uncertainty,
    separate-uncertainty = true,
]{siunitx}
\usepackage{expl3}
\ExplSyntaxOn
    \cs_new_eq:NN \fpcmpTF \fp_compare:nTF
\ExplSyntaxOff
\let\OldSI\SI%
\renewcommand*{\SI}[3][]{%
    \fpcmpTF{abs(#2)<=.001}{%
        \OldSI[scientific-notation=true,#1]{#2}{#3}%
    }{%
        \fpcmpTF{abs(#2)>=1000}{%
            \OldSI[scientific-notation=true,#1]{#2}{#3}%
        }{%
            \OldSI[scientific-notation=false,#1]{#2}{#3}%
        }%
    }%
}
\begin{document}
\SI{83}{\mega\pascal} looks good, \SI{83(22)}{\mega\pascal} doesn't.
\end{document}

The problem is I have some values with uncertainties (as in the above MWE) and (of course) the comparison to a threshold value (hardcoded here) fails, so the code above gives:
render of above .tex code

Now siunitx can parse 83(22) into two parts, so it must be possible, but haing spent some time staring at siunitx.sty and the expl3 manual I'm none the wiser.

Clearly I can work around this by saying [scientific-notation=false] before the latter example, but the point of the code-based solution is consistency (for avoiding small exponents).

So is there simple way to achieve output like (83 ± 22) MPa from the input I have? Or a beginners guide to writing in expl3?

Best Answer

Here I introduce a secondary parser \parseuncertainty which will separate out the mean value from the variation, and stuff them into two separate tokens. Then, your \SI command can compare against \SImeanvalue rather than #2.

\documentclass{article}
\RequirePackage[
    per-mode=reciprocal,
    scientific-notation=true,
    retain-explicit-plus,
    table-space-text-post=\textsuperscript{~a},
    table-align-text-post=true,
    table-align-exponent,
    table-align-uncertainty,
    separate-uncertainty = true,
]{siunitx}
\usepackage{expl3}
\ExplSyntaxOn
    \cs_new_eq:NN \fpcmpTF \fp_compare:nTF
\ExplSyntaxOff
\let\OldSI\SI%
\renewcommand*{\SI}[3][]{%
    \parseuncertainty#2()\relax%                             NEW
    \fpcmpTF{abs(\SImeanvalue)<=.001}{%                      ALTERED
        \OldSI[scientific-notation=true,#1]{#2}{#3}%
    }{%
        \fpcmpTF{abs(\SImeanvalue)>=1000}{%                  ALTERED
            \OldSI[scientific-notation=true,#1]{#2}{#3}%
        }{%
            \OldSI[scientific-notation=false,#1]{#2}{#3}%
        }%
    }%
}
\def\parseuncertainty#1(#2)#3\relax{%                        NEW
  \def\SImeanvalue{#1}\def\SIuncertainty{#2}}%               NEW
\begin{document}
\SI{83}{\mega\pascal} looks good, \SI{83(22)}{\mega\pascal} does too.\par
And \SI{12345(456)}{\mega\pascal} also.
\end{document}

enter image description here