20

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?

Sebastiano
  • 54,118
  • 2
    You want to print an arbitrary number of digits of e, like have \nepero{10} print 2.7182828459? – Phelype Oleinik Jan 04 '20 at 21:11
  • @PhelypeOleinik Yes, exactly. I have written into chat that: Any improvements in tags and English language into my recent question are very welcome. Thank you, everyone. But is it possible for any number? Thank you very much. – Sebastiano Jan 04 '20 at 21:13
  • 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 04 '20 at 21:16
  • I think you left off 18 between 2.71828 and 28459... :-) – Mico Jan 04 '20 at 23:17
  • 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 04 '20 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 05 '20 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 05 '20 at 12:23
  • 1
    This left me wondering for a while why it looks just like Euler's number. – IS4 Jan 05 '20 at 12:36
  • @Mico Thank you very much also to you for your support. :-) My students are surprise for my memory ahahhahah. But I am only a humble e little teacher. – Sebastiano Jan 05 '20 at 12:39
  • @IllidanS4wantsMonicaback It is true; the number e and is called Euler's number, while in Italy it is also called Napier's number. :-). You can see on Wikipedia: https://it.wikipedia.org/wiki/E_(costante_matematica) – Sebastiano Jan 05 '20 at 12:43

6 Answers6

21

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. :-)

ShreevatsaR
  • 45,428
  • 10
  • 117
  • 149
  • 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 05 '20 at 06: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 05 '20 at 07: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 05 '20 at 11:19
  • 1
    +1 for you and for all users :-). Thank you very much for your code that I have appreciated. – Sebastiano Jan 05 '20 at 12:43
16

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

egreg
  • 1,121,712
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}
Mico
  • 506,678
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}
cis
  • 8,073
  • 1
  • 16
  • 45
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

DJP
  • 12,451
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.

Fran
  • 80,769