
Предположим, у меня есть следующая таблица
\documentclass{article}
\usepackage{siunitx}
\begin{document}
\begin{table}
\begin{tabular}{S[table-alignment=right,
round-mode=places,
round-precision=1,
table-format=5.3,
zero-decimal-to-integer]}
{title} \\
11111 \\
11.11 \\
0.11 \\
\end{tabular}
\end{table}
\end{document}
и я хотел бы округлить числа так, чтобы числа выше 1 округлялись до целых чисел, а числа ниже 1 округлялись до первого десятичного знака. Результат здесь будет 11111, 11, 0.1
.
Я пробовал следующие комбинации, которые дали нежелательные результаты
round-mode=figures and round-precision=1: 10000, 10, 0.1
round-mode=figures and round-precision=5: 11111, 11.110, 0.11000
round-mode=places and round-precision=1: 11111, 11.1, 0.1
но я не могу разобраться с правильными настройками, чтобы получить то, что мне нужно (и надеюсь, что это будет достаточно распространено, чтобы это стало возможным в siunitx
).
решение1
Если это только для использования в таблицах, то вы можете использовать pgfplotstable
и предварительно обрабатывать числа. Ниже я определяю новый ключ, round int
который обеспечивает предварительную обработку.
\documentclass{article}
\usepackage{siunitx,pgfplotstable}
\pgfplotsset{compat=1.17}
\begin{document}
\makeatletter
\pgfplotsset{table/round int/.style={%
/pgfplots/table/preproc cell content/.append code={%
\pgfkeysgetvalue{/pgfplots/table/@cell content}\pgfmathresult
\ifx\pgfmathresult\pgfutil@empty
\else
\pgfmathparse{abs(\pgfmathresult) > 1 ? round(\pgfmathresult) : \pgfmathresult}%
\pgfkeyslet{/pgfplots/table/@cell content}\pgfmathresult
\fi}}}
\makeatother
\pgfplotstabletypeset[multicolumn names,
columns/0/.style={column name={title},
string type,
column type={S[table-alignment=right,
round-mode=places,
round-precision=1,
table-format=-5.1,
zero-decimal-to-integer]},
round int
}
]{
11111
11.11
11.85
0.11
0.19
-10.2
-10.8
}
\end{document}
К сожалению, стандарт, preproc/expr
включенный в пакет, pgfplotstable
имеет некоторые настройки, которые не подходят для ваших данных. Приведенный выше код основан на том, как preproc/expr
это реализовано в этом пакете.
Если вы хотите, чтобы числа в столбце были выровнены по правому краю, просто замените table-format
аргумент столбца S
на table-parse-only
:
\documentclass{article}
\usepackage{siunitx,pgfplotstable}
\pgfplotsset{compat=1.17}
\begin{document}
\makeatletter
\pgfplotsset{table/round int/.style={%
/pgfplots/table/preproc cell content/.append code={%
\pgfkeysgetvalue{/pgfplots/table/@cell content}\pgfmathresult
\ifx\pgfmathresult\pgfutil@empty
\else
\pgfmathparse{abs(\pgfmathresult) > 1 ? round(\pgfmathresult) : \pgfmathresult}%
\pgfkeyslet{/pgfplots/table/@cell content}\pgfmathresult
\fi}}}
\makeatother
\pgfplotstabletypeset[multicolumn names,
columns/0/.style={column name={title},
string type,
column type={S[table-alignment=right,
round-mode=places,
round-precision=1,
zero-decimal-to-integer,
table-parse-only]},
round int
}
]{
11111
11.11
11.85
0.11
0.19
-10.2
-10.8
}
\end{document}
решение2
Если вам необходимо использовать такую функцию как в таблице, так и вне ее в тексте, вы можете воспользоваться математическими функциями pgfmath
для определения \MyRoundMacro
:
\newcommand*{\MyRound}[1]{%
\pgfmathtruncatemacro{\@IntegerComponent}{abs(#1)}%
\ifnum\@IntegerComponent=0
\num[round-mode=places, round-precision=1]{#1}%
\else
\num{\@IntegerComponent}%
\fi
}%
Вы можете использовать это напрямую длякаждыйзапись в таблице или используйте collcell
пакет для определения пользовательского типа столбца R
и используйте его:
\newcolumntype{R}{>{\collectcell\MyRound}r<{\endcollectcell}}
где r
— желаемое выравнивание столбцов.
Таблицы, подготовленные MWE ниже, соответствуют пожеланиям:
Примечания:
- Использование
R
типа столбца требует, чтобы вы обернулилюбойне числовое содержимое (такое как строки заголовка) внутри\multicolumn{1}{c}{}
.
Код:
\documentclass{article}
\usepackage{siunitx}
\usepackage{collcell}% Needed only if desire to use the `R` column type defined below
\usepackage{pgfmath}
\begin{document}
\makeatletter
\newcommand*{\MyRound}[1]{%
\pgfmathtruncatemacro{\@IntegerComponent}{abs(#1)}%
\ifnum\@IntegerComponent=0
\num[round-mode=places, round-precision=1]{#1}%
\else
\num{\@IntegerComponent}%
\fi
}%
\makeatother
\newcolumntype{R}{>{\collectcell\MyRound}r<{\endcollectcell}}
In a table the \verb|R| column type (requires non data entries to be wrapped in a \verb|\multicolumn|):
\begin{tabular}{R}
\multicolumn{1}{c}{\bfseries title} \\
11111 \\
11.11 \\
0.11 \\
\end{tabular}
Can use the \verb|\MyRound| macro directly in a table and
outside of a table:
\begin{tabular}{r}
{\bfseries title} \\
\MyRound{11111} \\
\MyRound{11.11} \\
\MyRound{0.11} \\
\end{tabular}
Outside of a table:
\MyRound{11111}\par
\MyRound{11.11}\par
\MyRound{0.11}\par
\end{document}