21

My students are always very happy when I write a number of decimal digits of the transcendental Napier's number e. I only remember 30 decimal digits as from example. I remind all readers that I'm not an expert of the siunitx package. However, I do know that it is important to correctly process numbers, units and spaces in them. :-)

enter image description here

\documentclass{article}
\begin{document}
$e=2.718281828459045235360287471352\dots$
\end{document}

Using this widget from wolframalpha of Napier's number I have the possibility to choose the number of decimal places. Is it possible to do the same thing with LaTeX?

  • 2
    You want to print an arbitrary number of digits of e, like have \nepero{10} print 2.7182828459? – Phelype Oleinik Jan 4 at 21:11
  • 3
    just get alpha to give you the first 1000 digits store them in a tex file then a trivial tex macro will show as many as you want – David Carlisle Jan 4 at 21:16
  • 1
    @DavidCarlisle: I did exactly this – \documentclass{standalone} \usepackage{siunitx} \begin{document} \num[round-mode=places, round-precision=5]{2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993} \end{document} – Oleg Lobachev Jan 4 at 23:29
  • 1
    @Mico Yes....it is true. Without to seen 2.7182818284590456028747135. :-( I'm sorry. Have you edit the Napier's number, please? – Sebastiano Jan 5 at 11:56
  • 1
    @Sebastiano - I fixed the number. :-) (The only reason I noticed is because I've only ever memorized the number up to "18-28-18-28"... That makes 10 digits, counting the initial 2.) – Mico Jan 5 at 12:23
17

I saved 100 decimal digits of e.

\documentclass{article}
\usepackage{siunitx} % also loads expl3 and xparse

\ExplSyntaxOn

\tl_const:Nn \c_sebastiano_napier_tl
 {
  71828182845904523536
  02874713526624977572
  47093699959574966967
  62772407663035354759
  45713821785251664274
 }

\NewDocumentCommand{\napier}{m}
 {
  \num{ 2.\tl_range:Nnn \c_sebastiano_napier_tl { 1 } { #1 } }
 }

\ExplSyntaxOff

\begin{document}

\napier{2}

\napier{18}

\end{document}

enter image description here

With possible line breaks use \napier*.

\documentclass{article}
\usepackage{amsmath}
\usepackage{siunitx} % also loads expl3 and xparse
\showthe\thinmuskip
\ExplSyntaxOn

\tl_const:Nn \c_sebastiano_napier_tl
 {
  71828182845904523536
  02874713526624977572
  47093699959574966967
  62772407663035354759
  45713821785251664274
 }
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }

\NewDocumentCommand{\napier}{sm}
 {
  \IfBooleanTF { #1 }
   {
    \sebastiano_napier_inline:n { #2 }
   }
   {
    \num{ 2.\tl_range:Nnn \c_sebastiano_napier_tl { 1 } { #2 } }
   }
 }

\cs_new_protected:Nn \sebastiano_napier_inline:n
 {
  \seq_set_split:Nnx \l_tmpa_seq {} { \tl_range:Nnn \c_sebastiano_napier_tl { 1 } { #1 } }
  2.\seq_indexed_map_function:NN \l_tmpa_seq \__sebastiano_napier_split:nn
 }

\cs_new_protected:Nn \__sebastiano_napier_split:nn
 {
  #2
  \int_compare:nT { \int_mod:nn { #1 } { 3 } = 0 }
   {
    \mode_if_math:TF
     {
      \penalty \c_zero_int
      \mspace{1\thinmuskip plus 1\thinmuskip}
     }
     {
      \hspace{0.16667em plus 0.16667em}
     }
   }
 }

\ExplSyntaxOff

\begin{document}

\napier{2}

\napier{18}

\napier*{99}

$\napier*{99}$

\end{document}

enter image description here

| improve this answer | |
22

Just for fun, here's an answer using LuaTeX that does the computation of the digits of e in Lua, without external data, and should be good for ~10000 digits at least. (Actually in principle the algorithm should work fine (just taking very long) for billions of digits or even millions of billions depending on how Lua is compiled, but you'll run out of patience and/or memory sooner.)

\documentclass{article}
\usepackage{luacode}
\begin{luacode}
-- Takes time ~n^2 to compute n digits. Tolerable until about n=10000.
function digits_e(n)
    -- Spigot algorithm by Rabinowitz and Wagon:
    -- http://www.cecm.sfu.ca/~jborwein/Expbook/Manuscript/Related%20files/spigot.pdf
    -- The idea: Just as we can say that
    -- e = 2 + (7, 1, 8, 2, 8, ...) in base (1/10, 1/10, 1/10, 1/10, 1/10, ...)
    -- the fact that e = sum(1/k!) over k≥0 gives, in the same notation,
    -- e = 2 + (1, 1, 1, 1, 1, ...) in base (1/2, 1/3, 1/4, 1/5, 1/6, 1/7, ...)
    -- We convert to the decimal base by repeatedly multiplying by 10.

    local len = n + 2
    -- After k≥0 steps, fractional part of (e-2)10^k in base (1/2, 1/3, 1/4, ...)
    local a = {}; for j = 1, len do a[j] = 1 end

    tex.sprint('2.')
    for k = 1, n do
        local carry = 0  -- We're about to multiply by 10, right to left.
        for i = len, 1, -1 do
            local x = carry + 10 * a[i]
            a[i] = math.fmod(x, i + 1)
            carry = math.modf(x / (i + 1))
        end
        tex.sprint(carry)
        if k % 1000 == 0 then print(string.format('Done %d digits', k)) end
        if k % 3 == 0 then tex.sprint([[\hskip 1.66663pt plus 0.6pt\relax]]) end
    end
end
\end{luacode}

\newcommand\napier[1]{\directlua{tex.sprint(digits_e(#1))}}

\begin{document}
\napier{2}

\napier{18}

\napier{100} % Last 10 digits: ...525 166 427 4

\napier{1000} % Last 10 digits: ...957 035 035 4

\napier{10000} % Last 10 digits: ...946 553 678 8
\end{document}

output

  • The algorithm I repurposed from what I had used earlier for pi, though it's quite a bit simpler for e.

  • It's O(n^2) so a bit slow (takes a few seconds for 10000 digits). We can speed it up by a small constant factor (like 10) by multiplying by a power of 10 instead of by 10 itself. (See block in the second revision of this answer; reverted to keep the code clear and simple.)

  • The algorithm is simple enough (and uses only arithmetic on small numbers, of roughly the size of the number of digits requested) that I suspect it could even be implemented with TeX macros and sufficiently many registers. :-)

  • I tried to use \num from siunitx but it was hard to figure out how to typeset a long number without overfull box warnings and the like -- it seems that the package does not provide such a feature and it looks complicated. Eventually gave up and wrote \hskip manually into the Lua code. :-)

| improve this answer | |
  • 2
    +1. :-) The grouping performed by your code includes the integer part of the number e, i.e., the number 2. Could you change the code so that grouping is applied to the decimal part only? – Mico Jan 5 at 6:38
  • 1
    @Mico Ah good catch, an oversight while I was rewriting code... the fix is simply to change the ` if k % 3 == 0` to ` if k % 3 == 1` but before I update the answer I'm looking into something more... – ShreevatsaR Jan 5 at 7:16
  • 2
    @Mico The other thing I was trying didn't work out; fixed now and updated image. Thanks for pointing it out :-) – ShreevatsaR Jan 5 at 11:19
  • 1
    +1 for you and for all users :-). Thank you very much for your code that I have appreciated. – Sebastiano Jan 5 at 12:43
15

Here's a LuaLaTeX-based solution. It provides two LaTeX utility macros -- \ShowNum and \ShowGrNum -- as well as two Lua functions that perform the actual work.

Some comments:

  • Because Lua performs "just" double-precision calculations, you should not use this approach if you intend to show more than about 15 decimal digits. If you do intend to show more than 15 decimal digits, it's necessary to either pre-store the numbers of interest up to some desired level of precision, as is shown in @egreg's answer as well as in the addendum shown below, or to pursue an arbitrary-precision approach such as the one pursued in @ShreevatsaR's answer.

  • The LaTeX macro \ShowNum takes 2 arguments: The number itself, and the number of decimal digits to be shown. No grouping is performed.

    • The first argument of \ShowNum can be a constant, e.g., 12345.6789012, or something that can be evaluated meaningfully by Lua, e.g., math.exp(1), math.pi, 2*math.acos(0), or 2*math.asin(1).

    • The four arithmetic symbols +-*/ are ok in the first argument; however, don't use ^ (exponentiation) in the first argument of \ShowNum as LaTeX will interpret it as the start of superscript material. In general, be careful lest the first argument contain material that could get expanded by LaTeX in some unanticipated manner.

    • Of course, it's fine for the first argument of \ShowNum to contain LaTeX macros that expand to something that can be handled by Lua.

  • The macro \ShowGrNum takes the same 2 arguments as \ShowNum, plus an optional argument that determines the type of grouping. The optional argument should be an integer (aka a positive whole number). The default value of the optional argument is 3, i.e., the decimal part (but not the integer part) will be grouped in chunks of 3 digits by default. Note that \ShowGrNum allows line breaking after each group of numbers; this is in contrast to the properties of the \num macro of the siunitx package.

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function PrintNum ( n , m )
   -- n: number to be printed
   -- m: number of decimal digits to be shown
   return string.format ( "%."..m.."f" , n ) 
end   

function GroupNum ( s , g )
   -- s: number whose decimal part should be grouped
   -- g: number of digits in group (say, '3')
   s = tostring ( s )
   local m 
   m = s:find ( "%." ) -- find the integer part of 's'
   if m then -- print integer part first
     tex.sprint ( s:sub(1,m) ) -- no grouping applied
     s = s:sub(m+1)
   end
   -- Apply visual grouping to decimal part:
   while #s > g do
      tex.sprint ( s:sub(1,g) .. "\\hspace{0.1666em}\\allowbreak")
      s = s:sub(g+1) -- discard the first 'n' chars
   end
   tex.sprint ( s )
end   
\end{luacode}
%% Define 2 LaTeX macros:
%%   \ShowNum just prints the number
%%   \ShowGrNum additionally groups the number
\newcommand\ShowNum[2]{\directlua{%
   tex.sprint ( PrintNum ( #1 , #2 ) )}}
\newcommand\ShowGrNum[3][3]{\directlua{%
   GroupNum ( PrintNum ( #2 , #3 ) , #1 )}}

\begin{document}
\ShowNum{math.exp(1)}{15}

$\ShowNum{math.pi}{15}$

\smallskip
\ShowGrNum{math.exp(1)}{15}

$\ShowGrNum[4]{2*math.acos(0)}{15}$
\end{document}

Addendum: Just for fun, here's a version of the LuaLaTeX solution that stores the first 2000 decimal digits of Napier's number. Anywhere from 0 to 2000 digits can be shown via the LaTeX macro \Napier. The macro takes an optional argument: the number of digits in each group. (The default grouping number is 3.) As in the answer above, the grouping is performed with the help of Lua's powerful string.sub function.

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
-- store the first 2000 decimal digits of Napier's number as a string:
local napiernum = "71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170276183860626133138458300075204493382656029760673711320070932870912744374704723069697720931014169283681902551510865746377211125238978442505695369677078544996996794686445490598793163688923009879312773617821542499922957635148220826989519366803318252886939849646510582093923982948879332036250944311730123819706841614039701983767932068328237646480429531180232878250981945581530175671736133206981125099618188159304169035159888851934580727386673858942287922849989208680582574927961048419844436346324496848756023362482704197862320900216099023530436994184914631409343173814364054625315209618369088870701676839642437814059271456354906130310720851038375051011574770417189861068739696552126715468895703503540212340784981933432106817012100562788023519303322474501585390473041995777709350366041699732972508868769664035557071622684471625607988265178713419512466520103059212366771943252786753985589448969709640975459185695638023637016211204774272283648961342251644507818244235294863637214174023889344124796357437026375529444833799801612549227850925778256209262264832627793338656648162772516401910590049164499828931505660472580277863186415519565324425869829469593080191529872117255634754639644791014590409058629849679128740687050489585867174798546677575732056812884592054133405392200011378630094556068816674001698420558040336379537645203040243225661352783695117788386387443966253224985065499588623428189970773327617178392803494650143455889707194258639877275471096295374152111513683506275260232648472870392076431005958411661205452970302364725492966693811513732275364509888903136020572481765851180630364428123149655070475102544650117272115551948668508003685322818315219600373562527944951582841882947876108526398139"

function Napier ( n , g )
  -- n: number of decimal digits to be shown (0\le n \le 2000) 
  -- g: number of digits per group (3 by default)
  if n==0 then -- no decimal part to show
    tex.sprint ( "2" ) 
  else
    e = napiernum:sub ( 1 , n ) -- retain the first n digits
    tex.sprint "2."
    while #e>g do
      tex.sprint ( e:sub ( 1 , g ) .. "\\,\\allowbreak" )
      e = e:sub ( g+1 ) -- discard first g digits
    end
    tex.sprint ( e ) -- display remaining digits (if any)
  end
end
\end{luacode}
%% LaTeX macro to show first n digits of "e", grouped:
\newcommand\Napier[2][3]{\directlua{Napier(#2,#1)}}

\begin{document}
\raggedright
\Napier{0}, \Napier{1}, \Napier{9}

\smallskip
\Napier[8]{1024} % in groups of 8
\end{document}
| improve this answer | |
5

An implementation with the CAS Sage(math) and SageTeX:

enter image description here

I use arara: sagetex for compiling.

\documentclass[]{article}
\usepackage{sagetex}

% \groupify{<digits>}{<my number>}
% https://tex.stackexchange.com/a/522907/46023
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand \groupify { O{\,\allowbreak} m m }
  { \jakob_groupify:nnn {#1} {#2} {#3} }
\cs_new:Npn \jakob_groupify:nnn #1 #2 #3
  { \__jakob_groupify_loop:nnw { 1 } {#2} #3 \q_recursion_tail {#1} \q_recursion_stop }
\cs_new:Npn \__jakob_groupify_loop:nnw #1 #2 #3
  {
    \quark_if_recursion_tail_stop:n {#3}
    \exp_not:n {#3}
    \int_compare:nNnTF {#1} = {#2}
      { \__jakob_groupify_sep:n }
      { \exp_args:Nf \__jakob_groupify_loop:nnw { \int_eval:n { #1+1 } } }
          {#2}
  }
\cs_new:Npn \__jakob_groupify_sep:n #1 #2 \q_recursion_tail #3
  {
    \tl_if_empty:nF {#2} { \exp_not:n {#3} }
    \__jakob_groupify_loop:nnw { 1 } {#1}
    #2 \q_recursion_tail {#3}
  }
\ExplSyntaxOff

\begin{document}
\section{In}
\begin{sageblock}
def myexpdigts(n): return e.numerical_approx(digits=n)
def myoutput(n): return r"\groupify{3}{%s}"%(myexpdigts(n))
#print myoutput(111)
\end{sageblock}

\section{Out}
$e = \sagestr{myoutput(1234)}\dots$
\end{document}
| improve this answer | |
  • 2
    Every answer for me is welcome. Thank you very very much. – Sebastiano Jan 6 at 15:49
3

The sagetex answer can be shortened a bit by adapting PeterGrill's response to Formatting Decimals. Using the numprint package along with a minipage environment keeps the SAGE output from overflowing the line. As this will be useful with long SAGE output, I include the code below.

\documentclass[]{article}
\usepackage{sagetex,numprint}
\npdecimalsign{\ensuremath{.}}%
\npthousandsep{ }%
\begin{document}
\begin{sagesilent}
output = r"\begin{minipage}{.95\linewidth}"
output += r"\numprint{%s}"%(e.n(digits=1000))
output += r"\end{minipage}"
\end{sagesilent}
$\sagestr{output}$
\end{document}

The output is shown running in Cocalc:

enter image description here

| improve this answer | |
  • Thank you very very much also for you...I have an only vote...but I can do better. – Sebastiano Jan 6 at 19:42
1

With knitr:

\documentclass{article}
<<echo=F>>=
library(numbers)
@
\begin{document}
\Sexpr{dropletE(4)}\par
\Sexpr{dropletE(20)}\par
\Sexpr{dropletE(40)}
\end{document}

The output should be:

2.7182

2.71828182845904523536

2.7182818284590452353602874713526624977572

According to the numbers manual, above 1000 digits the output could be very slow.

| improve this answer | |
  • Fran thank you very very much for to give me another answer. Very very good and welcome always. – Sebastiano Jan 20 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.