考虑这个简单的例子。
\documentclass[12pt]{standalone}
\usepackage{siunitx}
\begin{document}
\begin{tabular}{S[group-separator={,}]}
123456789
\end{tabular}
显示为
123,456,789
在印度数字系统中,数字的分组略有不同。引用维基百科文章 小数分隔符:
印度的数字系统稍微复杂一些:它将最右边的三位数字组合在一起(直到百位),然后按两位数字的集合进行分组。例如,一万亿 [
10^{12}
] 因此可以写为10,00,00,00,00,000
或 10 kharab。
在这个特定的例子中,我想将数字分组为
12,34,56,789
更一般地,支持将数字分组为任意长度的组可能会很有用。如果没有这样的支持,解决方法/黑客可能会有所帮助。
请参阅相关的 GitHub 问题,功能要求:组分隔符以可变的数字分隔。
答案1
以下解决方案以“印度风格”(因为没有更好的术语)格式化大数字(准确地说是正整数)。该解决方案提供了一个名为的用户宏\indnum
,它依赖于 Lua 的字符串库,因此必须在 LuaLaTeX 下编译。
这种格式化方法与包兼容siunitx
,因为解决方案实际上依赖于\num
宏来格式化小于 100,000 的数字——哎呀,1,00,000。但是,数字不能直接用于类型的列中S
。另一方面,的参数不必是显式整数;只要参数根据 Lua 的语法规则计算为数字,\indnum
就可以输入诸如 之类的内容。2e8*4+20/4
补充说明:您在评论中声称“siunitx
的功能的一部分是数字格式”。就我个人而言,我实际上非常不同意您的说法——我会立即将其改为“siunitx
的功能之一是数字格式根据公认的 SI 原则“[强调]。我所知道的唯一这样的原则是以 1000 的乘法增量进行分组。在我看来,所有其他分组方法——包括大于 999 的数字以 100 的乘法增量——都不在该siunitx
软件包应该关注的范围内。当然,我很乐意让 Joseph Wright(该软件包的作者和维护者siunitx
)就这个问题发表自己的看法。
无论如何,我不明白为什么不能使用r
列类型来排版“印度风格”格式的数字。请参阅下表了解应用程序。
% !TEX TS-program = lualatex
\documentclass{article} % or some other suitable document class
\usepackage[group-separator={,},
group-minimum-digits=4,
input-decimal-markers={.}]{siunitx}
\usepackage{luacode} % for "luacode" environment
\begin{luacode}
function indnum ( n )
local s, t
n = math.floor ( n ) -- retain integer part
if n<1e5 then -- invoke "\num" macro to format and print
tex.sprint ( "\\num{" .. n .. "}" )
else
s = string.reverse ( "" .. n ) -- convert to string & reverse
t = s:sub(1,3) .. "," .. s:sub(4,5) .. ","
s = s:sub(6) -- discard first 5 digits of 's' string
while #s > 2 do
t = t .. s:sub(1,2) .. ","
s = s:sub(3) -- discard first 2 digits of 's' string
end
t = t .. s -- last step: 's' contains 0, 1, or 2 digits
tex.sprint ( string.reverse ( t ) ) -- reverse order and print
end
end
\end{luacode}
\newcommand\indnum[1]{\directlua{ indnum(#1) }}
\begin{document}
\begin{tabular}{r l}
\indnum{500}\\
\indnum{5e4}\\
\indnum{1e5} & 1 lakh\\
\indnum{1e7} & 1 crore\\
\indnum{2e8*4+20/4}\\
\indnum{123456789e1}\\
\indnum{123456789e2}\\
\indnum{123456789e3}\\
\indnum{123456789e4}
\end{tabular}
\end{document}
答案2
一种可能:效率不高并且使用内部方法,但目前这是唯一的方法:
\documentclass{article}
\usepackage{siunitx}
\ExplSyntaxOn
\cs_gset:Npn \__siunitx_number_output_integer_aux:n #1
{
\int_compare:nNnTF { \tl_count:n {#1} } > 3
{
\exp_args:Ne \__siunitx_number_output_integer_auxii:n
{ \tl_reverse:n {#1} }
}
{ \exp_not:n {#1} }
}
\cs_new:Npn \__siunitx_number_output_integer_auxii:n #1
{
\__siunitx_number_output_integer_auxiii:w #1
\q_recursion_tail \q_recursion_tail \q_recursion_stop
\__siunitx_number_output_integer_end:n { }
}
\cs_new:Npn \__siunitx_number_output_integer_auxiii:w #1#2#3
{
\__siunitx_number_output_integer_store:nw {#3#2#1}
\__siunitx_number_output_integer_auxiv:w
}
\cs_new:Npn \__siunitx_number_output_integer_auxiv:w #1#2
{
\quark_if_recursion_tail_stop:N #1
\quark_if_recursion_tail_stop_do:Nn #2
{ \__siunitx_number_output_integer_store:nw {#1} }
\__siunitx_number_output_integer_store:nw
{
#2#1
\str_if_eq:VnTF \l__siunitx_number_group_separator_tl { , }
{ \exp_not:N \mathord }
{ \use:n }
{ \exp_not:V \l__siunitx_number_group_separator_tl }
}
\__siunitx_number_output_integer_auxiv:w
}
\cs_new:Npn \__siunitx_number_output_integer_end:n #1
{ \exp_not:n {#1} }
\cs_new:Npn \__siunitx_number_output_integer_store:nw
#1#2 \__siunitx_number_output_integer_end:n #3
{
#2
\__siunitx_number_output_integer_end:n {#1#3}
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{S[group-separator={,}]}
123456789
\end{tabular}
\end{document}
答案3
您可以使用选项指定第一个组和后续组的大小:
digit-group-first-size=3,
digit-group-other-size=2,
group-separator={,},
下面,我定义\numI
使用上述选项并在第二行产生结果的宏:
代码:
\documentclass{article}
\usepackage{siunitx}
\sisetup{group-minimum-digits=4}
\newcommand{\numI}[1]{%
\num[
digit-group-first-size=3,
digit-group-other-size=2,
group-separator={,},
]{#1}%
}
\begin{document}
Default: $\num{123456789}$
Indian: $\numI{123456789}$
\end{document}