6

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?

  • I'm working on a major siunitx update: flexibility in scientific notation definitely on my 'to do' list. – Joseph Wright Mar 12 '14 at 18:39
4

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

  • Not only almost instant but I learnt something about the use of \def as well! Double thanks. – Chris H Mar 12 '14 at 19:01
  • 1
    @ChrisH While I've learned a lot about \def from many expert posts on this site, everything "cool" I learned about \def I learned from David Carlisle's esoteric solutions. There is a lot you can do with \def as a parser, just by structuring the input stream accordingly. – Steven B. Segletes Mar 12 '14 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.