3

Consider this simple example.

\documentclass[12pt]{standalone}
\usepackage{siunitx}
\begin{document}
\begin{tabular}{S[group-separator={,}]}
  123456789
\end{tabular}

This is displayed as

123,456,789

In the Indian numerical system, digits are grouped somewhat differently. To quote the Wikipedia article on Decimal separator:

The Indian numbering system is somewhat more complex: it groups the rightmost three digits together (until the hundreds place) and thereafter groups by sets of two digits. For example, one trillion [10^{12}] would thus be written as 10,00,00,00,00,000 or 10 kharab.

In this particular example, I would like to group the number as

12,34,56,789

More generally, support for grouping numbers together in groups of arbitrary length could be useful. In the absence of such support, a workaround/hack might be helpful.

See the related GitHub issue, Feature request: group separators a variable number of digits apart.

Mico
  • 506,678
Faheem Mitha
  • 7,778
  • Is your objective primarily to achieve -- for lack of a better term -- "Indian-style" grouping of large numbers? Or do you also intend to use Indian-formatted numbers in a column of type S, i.e., to align the formatted numbers on their implicit or explicit decimal markers? Separately, does a solution have to be based on the machinery of the siunitx package (as would appear to be implied by the title of your posting), or might a solution that works independently of the siunitx package be acceptable? Please advise. – Mico Sep 12 '21 at 06:47
  • HI Mico. Yes, for now I'd like 'Indian-style' grouping of large numbers. And yes, I do intend to use Indian-formatted numbers in a S column. In fact, if it was available right now, that's what I would be doing. And I'd like a solution integrated with the rest of the siunitx machinery (whatever that might be), Given that part of siunitx's functionality is number formatting, that seems like a reasonable prospective feature/enhancement. I don't know whether a solution independent of the siunitx machinery would be acceptable. But at any rate, it would need to coexist with sinuitx. – Faheem Mitha Sep 12 '21 at 09:02

3 Answers3

2

The following solution formats large numbers -- positive integers, to be precise -- in "Indian style" (for lack of a better term). The solution, which provides a user macro called \indnum, relies on Lua's string library and hence must be compiled under LuaLaTeX.

This formatting method is compatible with the siunitx package in the sense that the solution actually relies on the \num macro to format numbers smaller than 100,000 -- oops, 1,00,000. However, the numbers cannot be employed directly in a column of type S. On the other hand, the argument of \indnum needn't be an explicit integer; it's fine to input something such as 2e8*4+20/4, as long as the argument evaluates to a number according to Lua's rules of syntax.

A side-remark: You claimed in a comment that "part of siunitx's functionality is number formatting". Speaking for myself, I actually strongly disagree with your claim -- and I'd immediately change it to "part of siunitx's functionality is number formatting according to recognized SI principles" [emphasis added]. The only such principle I know of is grouping in multiplicative increments of 1000. In my opinion, all other grouping methods -- including multiplicative increments of 100 for numbers greater than 999 -- are therefore not in the scope of what the siunitx package should be concerned with. Naturally, I will happily let Joseph Wright (the author and maintainer of the siunitx package) weigh in with his own opinion on this topic.

At any rate, I can't see why one couldn't use the r column type to typeset numbers formatted in the "Indian style". See the table below for an application.

enter image description here

% !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}
Mico
  • 506,678
  • Hi Mico. Thank you for the answer. I don't know whether the scope of this package is restricted to SI, but if so, perhaps you are right that this request is out of scope. My concern with Lua methods is whether they would conflict with siunitx's own machinery. Since siunitx uses different machinery. expl3, and possibly other things. Abd of course I'd certainly want such methods to integrate with siunitx, so one could use it as part of an S column, for example. – Faheem Mitha Sep 12 '21 at 12:05
  • @FaheemMitha - Why would the siunitx code conflict with LaTeX macros that internally use Lua? – Mico Sep 12 '21 at 12:06
  • 1
    @FaheemMitha - And, why can't you use the r column type, as I explained in my answer? Put differently, why would you want to use the S column type for numbers that have already been formatted according to 'Indian style'? – Mico Sep 12 '21 at 12:07
  • Instead of "conflict", perhaps "not integrate"? If I use the r column type, then can I get the other siunitx formatting for that columns too? Eg. rounding, decimal padding, possibly aligned with the decimal point? No, the answer is fine. I use Lua methods all the time. I just wasn't sure if it would work in this scenario. – Faheem Mitha Sep 12 '21 at 12:10
  • 1
    @FaheemMitha - As I wrote in my answer, the code works just fine with the siunitx package. In fact, for numbers smaller than 100000, \indnum relies on \num to get the formatting job done. I thus can't see why you'd say that the code in my answer isn't "integrated" with siunitx. Except, of course, if you're demanding an entire new feature request. However, feature requests are out of bounds for this site. If you're making a feature request, you should be making it directly to Joseph Wright, and not to TeX.SE. – Mico Sep 12 '21 at 12:14
  • Perhaps your code would still work if applied to a S column? But I have not tried it yet. – Faheem Mitha Sep 12 '21 at 12:16
  • @FaheemMitha - Why do you think I wrote "the numbers [formatted by \indnum] cannot be employed directly in a column of type S"? – Mico Sep 12 '21 at 12:18
  • Sorry, I didn't see that part. Anyway, please don't delete your answer. – Faheem Mitha Sep 12 '21 at 12:19
2

One possible: not efficient and using internals, but at present that's the only way:

\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}

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
  • Thank you for the answer. I tested it. I'm getting an error if I choose the mode=text option. I.e. If I replace \usepackage{siunitx} with \usepackage[mode=text]{siunitx} in your code. Can you reproduce this? – Faheem Mitha Sep 13 '21 at 19:19
  • The error looks like `! Missing $ inserted. $ l.52 \end {tabular}` – Faheem Mitha Sep 13 '21 at 19:23
  • @FaheemMitha Quite possibly: this was very much a first-pass hack - I assumed math mode. I can see how to fix, but this is getting quite a way beyond a quick adjustment. – Joseph Wright Sep 13 '21 at 19:23
  • I also wondered on your take on Mico's comment, when he said such a feature was outside the package's scope, since it wasn't part of "recognized SI principles". I don't have an opinion about this, because I don't even know what "recognized SI principles" are. Would such considerations influence in adding features to siunitx? – Faheem Mitha Sep 13 '21 at 19:27
  • @FaheemMitha Yes: there's a reason I ask about examples from the published literature. People make requests that are basically their personal preference, and I have to have some way of deciding. – Joseph Wright Sep 13 '21 at 19:32
  • I haven't found any documented usage of this notation in published articles or books. If I do, I'll add a comment here. Presumably Wikipedia itself does not count. – Faheem Mitha Sep 13 '21 at 19:35
  • @FaheemMitha Indeed: Wikipedia tells me it's a know approach for 'some content', but not for formal publications – Joseph Wright Sep 13 '21 at 19:43
2

You can use the options to specify the size of the first group and the subsequent groups:

    digit-group-first-size=3,
    digit-group-other-size=2,
    group-separator={,},

Below, I define the \numI macro which uses the above options and produces the result on the second line:

enter image description here

Code:

\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}

Peter Grill
  • 223,288