UPDATE: Bruno le Floch gave a great suggestion in the comments on one of the answers to How to subtract both very large numbers and numbers smaller than one?. This now makes it possible to use very large numbers in the range of plus/minus [1e-10000,1e10000].
He uses the package expl3
to define a comparison (test which of the numbers is less or greater):
\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \fpcmpTF \fp_compare:nTF
\ExplSyntaxOff
An MWE that only uses scientific notations for very small (now defined as 0.01) and very large (100 in this case) numbers is the following.
\documentclass{article}
\usepackage{expl3,siunitx}
\sisetup{scientific-notation=true}
\ExplSyntaxOn
\cs_new_eq:NN \fpcmpTF \fp_compare:nTF
\ExplSyntaxOff
%Edit these as you wish:
\newcommand*{\ThresholdLow}{0.01}
\newcommand*{\ThresholdHigh}{100}
\let\OldNum\num%
\renewcommand*{\num}[2][]{%
\fpcmpTF{abs(#2)<=\ThresholdLow}{%
\OldNum[scientific-notation=true,#1]{#2}%
}{%
\fpcmpTF{abs(#2)>=\ThresholdHigh}{%
\OldNum[scientific-notation=true,#1]{#2}%
}{%
\OldNum[scientific-notation=false,#1]{#2}%
}%
}%
}%
\begin{document}
\newcommand{\Row}[1]{#1 & \OldNum{#1} & \num{#1}}%
\begin{tabular}{l l l}
Num & Old & New\\\hline\\[-0.7em]
\Row{0.01}\\
\Row{0.1}\\
\Row{1}\\
\Row{10}\\
\Row{100}\\
\end{tabular}
\end{document}
A different way this solution can be used is by making a new .sty
-file that you save as for example threshold.sty
, in which you copy-paste the following:
\RequirePackage{expl3,kvoptions,siunitx}
\SetupKeyvalOptions{family=threshold,prefix=threshold@}
\DeclareStringOption[1]{low}[0.01]
\DeclareStringOption[1]{high}[100]
\ProcessKeyvalOptions*
\sisetup{scientific-notation=true}
\ExplSyntaxOn
\cs_new_eq:NN \fpcmpTF \fp_compare:nTF
\ExplSyntaxOff
\let\OldNum\num%
\renewcommand*{\num}[2][]{%
\fpcmpTF{abs(#2)<=\threshold@low}{%
\OldNum[scientific-notation=true,#1]{#2}%
}{%
\fpcmpTF{abs(#2)>=\threshold@high}{%
\OldNum[scientific-notation=true,#1]{#2}%
}{%
\OldNum[scientific-notation=false,#1]{#2}%
}%
}%
}
and which you then call using for example \usepackage[low=1e-2,high=1e2]{threshold}
.
The advantage of this is that you can use it more easily in other files, and that it doesn't take up so much space in the file you're editing. Also, it is more flexible, as you can just decide not to use any threshold and call the package without any argument (\usepackage{threshold}
), which then essentially does the same as just using \usepackage{siunitx}
. An other option is to use the arguments [low,high]
when using the package, which then uses the default settings for the low and high thresholds (using scientific notation only for numbers outside the range ±[-0.01,100]).
This is 'status-bydesign': the format used by siunitx
for numbers allows for only one exponent. The logic is that a number and it's uncertainly should necessaries have the same exponent, and thus giving two exponents is an error. Adding more flexibility to the current parser is not a realistic option, both for complexity and speed reasons.
There is an open feature request for 'plugable' approach to parsing numbers: I am committed to doing this in principle but currently have no time frame on it (far from trivial work, of which I have lots!).
Best Answer
If you can use LuaLaTeX instead of pdfLaTeX, it may be easier to just create a dedicated Lua function and set up an associated TeX "wrapper macro" rather than to try to hack the
\num
macro of thesiunitx
package. In the example below, the wrapper macro is called\mynum
, and its syntax is set up to be mimic the behavior of the\num
macro.The only assumption that's made about about the numbers to be formatted is that their exponent part is non-empty, i.e., that the numbers contain an
e<nn>
substring, where<nn>
is a positive or negative integer. With this setup, a number such ase1234
is a valid input for\mynum
(and for\num
too).Addendum: If you wanted to highlight the exponent in red instead of using bold-facing, you'd need to change
\\mathbf{%2}
in the Lua code to\\color{red}%2
. Of course, either thexcolor
orcolor
package needs to be loaded in order to get access to the\color
macro.