我有一张满是数字的表格。其中大多数是小于 1 的浮点数,有些是 1-100 的整数,还有一些是大数 (×10^75)。我知道如何设置小数的精度,siunitx
以便它们都能很好地排列,但我希望整数保持原样,大数(并且只有大数!)以科学计数法表示。
有没有办法自动将任何大于 100 的数字设置为科学计数法格式,同时将较小的数字保留为标准十进制表示法,将中间数字保留为整数?中间数字自动发生并不那么重要,因为它们总是在某一行,所以我可以简单地将它们视为文本。
编辑:这是一个 MWE。
\documentclass[11pt,a4paper,twoside]{book}
\usepackage[top=30mm, bottom=30mm, left=40mm, right=20mm]{geometry}
\usepackage{fancyhdr}
\pagestyle{fancy}
\setlength{\headheight}{15pt}
\usepackage{siunitx}
\sisetup{round-mode=places,round-precision=6}
\begin{document}
\begin{table}
%\begin{center}
\centering
\caption{Example table for Ask-Ubuntu.}
\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}
答案1
更新:Bruno le Floch 给了很好的建议在对其中一个答案的评论中如何减去非常大的数字和小于一的数字?。这样现在就可以使用正负 [1e-10000,1e10000] 范围内的非常大的数字。
他使用该包expl3
来定义一个比较(测试哪个数字小于或大于):
\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \fpcmpTF \fp_compare:nTF
\ExplSyntaxOff
以下是仅对非常小(现在定义为 0.01)和非常大(在本例中为 100)的数字使用科学计数法的 MWE。
\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}
此解决方案的另一种使用方法是创建一个新.sty
文件,并将其另存为,例如threshold.sty
,在其中复制粘贴以下内容:
\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}%
}%
}%
}
然后您可以使用例如来调用它\usepackage[low=1e-2,high=1e2]{threshold}
。
这样做的好处是,您可以更轻松地在其他文件中使用它,并且它不会占用您正在编辑的文件中太多空间。此外,它更灵活,因为您可以决定不使用任何阈值,并在不带任何参数的情况下调用包(\usepackage{threshold}
),这基本上与仅使用相同\usepackage{siunitx}
。另一个选项是在使用包时使用参数[low,high]
,然后使用低阈值和高阈值的默认设置(仅对范围 ±[-0.01,100] 之外的数字使用科学计数法)。
答案2
我正在为 v3.2 寻找这个。阈值的原型实现:键名等目前尚未修复。
\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}