# Scientific Notation Only For Large Numbers

I have a table full of numbers. Most of them are floating point numbers that are less than one, some are integers from 1-100, and a few are large (×10^75). I know how to set the precision of the small numbers using siunitx so that they all line up nicely, but I'd like the whole numbers to stay as they are and the large numbers (and only the large ones!) to be put in to scientific notation.

Is there a way to automatically set any number larger than 100 to be formatted in scientific notation, while leaving the smaller numbers in standard decimal notation and the intermediate numbers as integers? The intermediate numbers are less important to happen automatically, as they're always in a certain row, so I can simply treat them as text.

EDIT: Here is a MWE.

\documentclass[11pt,a4paper,twoside]{book}
\usepackage[top=30mm, bottom=30mm, left=40mm, right=20mm]{geometry}

\usepackage{fancyhdr}
\pagestyle{fancy}

\usepackage{siunitx}
\sisetup{round-mode=places,round-precision=6}

\begin{document}

\begin{table}
%\begin{center}
\centering

\begin{tabular}{rr|rrr}

&       & Control Case & History & No History \\

\hline & A & \num{0.143392788} & \num{9026780216140000000000} & \num{0.192293062} \\
file & B    & \num{0.002162212} & \num{-725293214339000000000} & \num{0.004052388} \\
& C  & 98    & 75    & 65 \\
\end{tabular}%

\label{t:example_table}
\end{table}

\end{document}

• t would be helpful if you composed a fully compilable MWE including \documentclass and the appropriate packages that sets up the problem. While solving problems can be fun, setting them up is not. Then, those trying to help can simply cut and paste your MWE and get started on solving the problem. May 1, 2013 at 7:06
• I can think of a way using the collcell package, but will wait in case there is some option built into the siunitx package May 1, 2013 at 7:08
• Have a look at tex.stackexchange.com/questions/45534/…. It seems related. May 1, 2013 at 8:06
• @Betohaku: Thanks for finding that as that was what I was thinking of. Had forgotten that I had done it already. :-) @ thornate: If the linked question answers the question let us know so we can close this as a duplicate. May 1, 2013 at 9:03
• siunitx doesn't have this feature yet. See this issue. May 1, 2013 at 11:00

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]).

• Yeah, but this does not quite work for the really really large numbers give in the MWE. May 8, 2013 at 6:30
• @PeterGrill Hm, you're right. Did your initial answer at tex.stackexchange.com/questions/45534/… work for really really small numbers? It's the pgfmathparse that's the bottleneck, isn't it? Is there anything we can use to replace this? May 8, 2013 at 6:33
• Yeah there must be an answer here on this site that can be adapted for that. I think there was an answer on the Fibonacci sequence that use a package to handle large numbers. If you search for that answer, should help to arrive at a solution. May 8, 2013 at 6:37
• @PeterGrill tex.stackexchange.com/questions/51414/fibonacci-numbers says we can use the bigintcalc package. I'll give it a try. May 8, 2013 at 6:39

I am looking at this for v3.2. A prototype implementation for a threshold: key names, etc. at present not fixed.

\documentclass{article}
\usepackage{siunitx}
\ExplSyntaxOn
\keys_define:nn { siunitx }
{
exponent-mode / threshold .code:n =
{ \tl_set:Nn \l__siunitx_number_exponent_mode_tl {#1} } ,
exponent-threshold-range .code:n =
{ \__siunitx_number_set_thresholds:n {#1} }
}
\cs_new_protected:Npx \__siunitx_number_set_thresholds:n #1
{
\exp_not:N \__siunitx_number_set_thresholds:w
#1 \token_to_str:N : \token_to_str:N : \exp_not:N \q_stop
}
\use:x
{
\cs_new_protected:Npn \exp_not:N \__siunitx_number_set_thresholds:w
##1 \token_to_str:N : ##2 \token_to_str:N : ##3 \exp_not:N \q_stop
}
{
\__siunitx_number_set_threshold:nn { lower } {#1}
\__siunitx_number_set_threshold:nn { upper } {#2}
}
\cs_new_protected:Npn \__siunitx_number_set_threshold:nn #1#2
{ \int_set:cn { l__siunitx_number_ #1 _threshold_int } { 0 #2 } }
\int_new:N \l__siunitx_number_lower_threshold_int
\int_new:N \l__siunitx_number_upper_threshold_int
\cs_new:Npn \__siunitx_number_exponent_threshold:nnnnnnn #1#2#3#4#5#6#7
{
\exp_args:Ne \__siunitx_number_exponent_threshold:nn
{
\__siunitx_number_exponent_scientific:nnnnnnn
{#1} {#2} {#3} {#4} {#5} {#6} {#7}
}
{ {#1} {#2} {#3} {#4} {#5} {#6} {#7} }
}
\cs_new:Npn  \__siunitx_number_exponent_threshold:nn #1#2
{ \__siunitx_number_exponent_threshold:nnnnnnnn #1 {#2} }
\cs_new:Npn  \__siunitx_number_exponent_threshold:nnnnnnnn #1#2#3#4#5#6#7#8
{
\bool_lazy_and:nnTF
{ \int_compare_p:nNn {#6#7} > \l__siunitx_number_lower_threshold_int }
{ \int_compare_p:nNn {#6#7} < \l__siunitx_number_upper_threshold_int }
{ \exp_not:n {#8} }
{ \exp_not:n { {#1} {#2} {#3} {#4} {#5} {#6} {#7} } }
}
\ExplSyntaxOff
\sisetup{exponent-threshold-range = -2:2 }
\begin{document}
\newcommand{\Row}[1]{#1 & \num[exponent-mode = scientific]{#1} & \num[exponent-mode = threshold]{#1}}%
\begin{tabular}{l l l}
Num & Old & New\\\hline\\[-0.7em]
\Row{0.01}\\
\Row{0.1}\\
\Row{1}\\
\Row{10}\\
\Row{100}\\
\Row{1234567890123}
\end{tabular}
\end{document}