35

What command could print pi for me? I want to specify how many digits it prints, I couldn't find anything online. I just want to be able to print pi.

  • 28
    Take your pick of languages: rosettacode.org/wiki/Pi – Mark Plotnick Nov 5 '14 at 20:30
  • 4
    Note that it gets more fun if you want more digits than around 15. – Thorbjørn Ravn Andersen Nov 6 '14 at 18:41
  • 2
    @DisplayName: it means that you can no longer use any program that internally stores/calculates PI using double precision floating point values (which is usually the highest precision "built-in" FP data type available in most languages). – Matteo Italia Nov 6 '14 at 21:51
  • 5
    My solution, decades ago before this was commonly provided by language libraries, was to memorize it to more places than the floating points I was using would ever need: 3.1415926535897932384626 is usually close enough for practical purposes, and even most impractical ones -- anything real-world is going to have more error than that in the other numbers, and for theoreticals I'd stick with the symbolic rather than numeric value. – keshlam Nov 7 '14 at 5:50
  • 3
    @syntaxerror interest is irrelevant. If you were to post a question asking for naked pictures of celebrities, it would get thousands of views and quite possibly upvotes. That does not make it on topic. This question is a classic example of too broad. Just look at the number of answers. Also note that the OP did not specify any limitations which makes the possible answers essentially infinite. In any case, closing is not deleting. The question and all of its 23 answers will still be here. Closing just means that no more answers are accepted. Do we really need even more ways to print π? – terdon Nov 11 '14 at 13:40

20 Answers 20

52

You can use this command:

echo "scale=5; 4*a(1)" | bc -l
3.14159

Where scale is the number of digits after decimal point.

Reference: http://www.tux-planet.fr/calculer-le-chiffre-pi-en-ligne-de-commande-sous-linux/

  • 12
    Shorter version in bash and other shells supporting here strings: bc -l <<< "scale=5; 4*a(1)". – pabouk Nov 6 '14 at 9:37
  • 2
    I wonder how many digits this can go? – DisplayName Nov 6 '14 at 16:42
  • 4
    @DisplayName quite a few. scale=1000 gives 999 correct digits rather quickly (the last digit is off by 1, reasonable since we're computing pi/4 and then multiplying by 4). scale=4000 gives 4000 correct digits in a few seconds. scale=10000 takes longer than I have patience for, but probably gives 9999 or 10000 correct digits. – hobbs Nov 6 '14 at 18:18
  • 4
    This gives an incorrect result on my machine, typing 'echo "scale=5; 4*a(1)" | bc -l' returns 3.14156, when the last digit should by 9 – Jordan Bentley Nov 6 '14 at 21:04
  • 1
    @JordanBentley, I have added an answer with correct rounding of the result. – pabouk Nov 7 '14 at 9:29
62

If you have tex(1) installed:

tex --version | head -1 | cut -f2 -d' '
  • 13
    This is almost worth an upvote just for being clever. Though the output of this changes when you upgrade the package. Shall we consider that to be a feature or a bug? – a CVn Nov 5 '14 at 20:26
  • 8
    @MichaelKjörling Actually, it changes to be a more precise approximation of pi. – Abrixas2 Nov 5 '14 at 20:27
  • @Abrixas2 Yes, I know. With the last version of TeX being version π. – a CVn Nov 5 '14 at 20:29
  • 30
    @DavidRicherby Fewer digits can be printed via an additional invocation of cut. More digits can be printed by waiting a long time and running the command again. – Steven D Nov 6 '14 at 10:59
  • 1
    @Ruslan depends on the implementation. I would expect in this particular case that it would be done "right". – Thorbjørn Ravn Andersen Nov 7 '14 at 19:13
23

For printing with arbitrary precision, you could use bc and the formula pi = 4*atan(1):

# bc -l
scale=<your precision>
4*a(1)
  • 2
    There's something funny about the scale option, pi = 3.141592.. but with echo "scale=5; 4*a(1)" | bc -l => 3.14156 I would then expect to see 3.14159 ? – fduff Nov 5 '14 at 21:10
  • 7
    scale specifies the precision to use for calculation, so with scale=5, no operation will use more than five fractional digits for any atomic operation. – Abrixas2 Nov 5 '14 at 21:14
  • @fduff, I have added an answer with correct rounding of the result. – pabouk Nov 7 '14 at 9:30
20

If you want something that can compute the value of π, then there are several approaches. Perhaps the most obvious solution would be to use a ready-made package like pi (Debian package link), which if Debian's package description is to be trusted can compute the value to an arbitrary precision, limited only by memory.

pi is actually an example that's included with the CLN library (Class Library for Numbers). It includes example applications that provide tools for generating arbitrary lengths of numbers such as Pi, Fibonacci, etc. CLN packages are available pre-packaged in Debian/Ubuntu (that's what the Debian link above is pointing to).

Examples
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

NOTE: The source of these examples is here in the source for the CLN code base.

Other distros

Fedora

On Fedora I had to download the source tarball and build it myself, but it builds with little fuss. For whatever reason the package cln on Fedora includes just the library but neglects the examples that are available in the Debian/Ubuntu version (above).

Arch

Arch provides the same program in the cln package (thanks Amphiteót).

  • Yeah, heh I meant the total value i just typed what i had in my head. – DisplayName Nov 5 '14 at 20:28
  • 2
    The "total value"?? Meaning what...? – Kyle Strand Nov 5 '14 at 22:37
  • 2
    @DisplayName read the rest of the answer. A dedicated program like pi sounds like exactly what you're looking for. You can do things like pi 300 to print the first 300 digits for example. – terdon Nov 5 '14 at 23:22
  • 3
    @KyleStrand I have discovered a truly marvellous answer to that, which this comment is too narrow to contain. Hey, it worked for Fermat! – terdon Nov 5 '14 at 23:25
  • I would love to know why this has received two downvotes. Did the people who downvoted not read the answer before they decided it was not useful? – a CVn Nov 6 '14 at 9:40
17

For up to a million digits you can use the following (here for 3000 digits):

curl --silent http://www.angio.net/pi/digits/pi1000000.txt | cut -c1-3000
  • 2
    This has the additional benefit that it should be reasonably close to O(1) complexity. Or maybe that isn't a benefit after all... – a CVn Nov 5 '14 at 20:53
  • 7
    Also, it's difficult to say that any network interaction is O(1) time complexity in a practical world. :P – HalosGhost Nov 6 '14 at 0:12
  • 2
    @HalosGhost For our purposes (compared to computing n digits of pi each time), downloading a fixed amount of data from a specific server over a network is likely to be effectively O(1), whereas computing n digits of pi is likely to be at least something like O(log n) and quite possibly higher (I'm not familiar with those algorithms). The actual download of the data is likely to take significantly more time than the overhead to start the download, hence the download time dominates and you get somewhere in the vicinity of O(1) given a reasonably fixed data transmission rate. Hence O(1). – a CVn Nov 6 '14 at 9:47
  • 4
    @MichaelKjörling When you say O(1) don't you actually mean O(n)? The download time in linear in the number of digits you need, hence O(n). – CodesInChaos Nov 6 '14 at 12:18
  • 1
    @CodesInChaos No, the download time is constant (given constant transmission rate) because you are downloading a constant number of digits (one million, here). Unless (in this specific case) curl is smart enough to print while downloading and stop downloading once the pipe breaks because cut exits? If that is the case, I agree, it would be O(n). – a CVn Nov 6 '14 at 12:36
15

Some of the other answers show incorrect digits at the last places of the output. Below is a variation of the answer using bc but with a correctly rounded result. The variable s contains the number of significant digits (including 3 in front of the decimal point).

Round half up

$ bc -l <<< "s=5; scale=s+2; pi=4*a(1)+5*10^(-s); scale=s-1; pi/1"
3.1416

Round down (truncate)

$ bc -l <<< "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1"
3.1415

Explanation of the rounding

The rounding is performed directly in bc. This does not have the limitation of the command printf which uses the C language double type representation for the numbers which has a precision of about 17 significant digits. See the answer with printf rounding.

scale=s-1 sets the number of digits to truncate to. pi/1 divides the result by 1 to apply the truncation. Simple pi does not truncate the number.

Rounding half up requires to add 5 to the first digit which will be cut off (5×10-s) so that in case of digits higher of equal 5 the last digit which will remain will be incremented.

From the tests by hobbs it seems that three additional digits which will be rounded / cut off (scale=s+2) will suffice even for very long numbers.

Here strings

The examples above use here strings which are supported for example in bash, ksh and zsh. If your shell does not support here string use echo and pipe instead:

$ echo "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1" |  bc -l
3.1415
  • 2
    Computing three additional digits for the purpose of rounding is not “correct rounding” as you claim in a comment. First, you don't have a bound on the error of the computation. If it can be wrong by 3 units in the last place as claimed by fduff, why wouldn't it be wrong by 1000 units in the last place? Second, see “the table maker's dilemma”. – Complicated see bio Nov 10 '14 at 17:59
12

perl one line (using bignum):

perl -Mbignum=bpi -wle 'print bpi(NUM)'

e.g

perl -Mbignum=bpi -wle 'print bpi(6)'
3.14159
  • For 10.000 digits: Close to 8 minutes in perl, less than 4 in bc. Not the fastest. – Isaac Oct 30 '18 at 8:38
9

With python2:

$ python -c "import math; print(str(math.pi)[:7])"
3.14159
  • 4
    For completeness's sake, this solution is python2-specific. – HalosGhost Nov 5 '14 at 22:36
  • After the edit, with the (..) this works in Python 2 and 3. Only seems to have 12 digits. – Anthon Nov 6 '14 at 12:44
  • $ python -c "import math; print(format(math.pi, '.400f'))" 3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 – Artem Shitov Nov 7 '14 at 17:05
  • 1
    @ArtemShitov - my bad, try importing gmpy2 (if you have it installed): python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])". Increase precision for more digits... e.g. python -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])" – don_crissti Nov 8 '14 at 1:15
  • 1
    The fastest I could find was from mpmath import mp; mp.dps = 1000000 ; print(mp.pi) just a couple of seconds for a million digits. Not bad at all !!!. – Isaac Oct 30 '18 at 9:17
7

Using Ruby:

require "bigdecimal"
require "bigdecimal/math"
include BigMath

BigDecimal(PI(100)).round(9).to_s("F")

3.141592654
  • 1
    One liner: ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")' – user44370 Nov 6 '14 at 0:06
4

In bash:

$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884
  • @Amphiteóth afmtodit requires groff to be installed. Here on Ubuntu (& flavors), it is not standard. JFYI. – syntaxerror Nov 11 '14 at 7:34
  • @syntaxerror Thank you, good point! I have removed my example. My point was just when read this A I ran grep on my system searching for the constant and found it in more than one places. That's why this was +1 for me! – user44370 Nov 11 '14 at 7:52
3

Very simple in PHP using the built in pi() function:

<?php 
echo round(pi(), 2);
?>
  • 1
    Can you edit this to give a command line version? – curiousdannii Nov 10 '14 at 9:01
3

How did I miss this question...

Here's a little Python pi program of mine that I posted a couple of weeks ago on Stack Overflow. It's not particularly fast, but it can do lots of digits. :) However, as I mentioned in that thread, I generally use Python's mpmath module for arbitrary precision arithmetic, and mpmath has a rather fast pi maker.

Eg,

time python -c "from mpmath import mp;mp.dps=500000;print mp.pi" >bigpi

real    0m4.709s
user    0m4.556s
sys     0m0.084s

500000 decimals of pi in under 5 seconds isn't too shabby, IMHO, considering it's running on a machine with a single core 2GHz processor, 2 gig of RAM, and writing to an elderly IDE drive.

  • Try from mpmath import mp; mp.dps = 1000000 ; print(mp.pi) (after a pip3 install mpmath) under two seconds for a million digits. Not bad at all !!!. – Isaac Oct 31 '18 at 1:22
2

If you have node.js installed, this will do its best at finding pi for you, though its best isn't very good:

node -e 'for(a=0,b=4E8,m=Math,r=m.random;b--;)a+=(1>m.sqrt((c=r())*c+(d=r())*d));console.log(a/1E8)'

Sample outputs:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371
  • 4
    The shorter node -e 'console.log(Math.PI)' is a little better than its best. – chbrown Nov 6 '14 at 4:45
  • 1
    @chbrown That doesn't satisfy the OPs "not serious" requirement. – Paul Nov 6 '14 at 12:55
  • 1
    What "not serious" requirement? The OP just stated that they're asking for fun not that they want answers that are somehow "not serious". What does that mean anyway? Something like echo pie? – terdon Nov 6 '14 at 13:42
  • I typed that because when you ask questions sometimes people say that "this is not a script writing factory", so i said that because theres no real reason for it, i just want to know how to print pi. – DisplayName Nov 6 '14 at 16:08
  • @Amphiteóth It takes about 20 seconds to run on my computer. You might just need to give it some time. – Paul Nov 7 '14 at 13:04
2

Monte Carlo Method

See, for example, this for an explanation of this method.

Caveats

  • Not arbitrarily accurate
  • Takes a long time to converge to anything useful

Advantages

Fun :-)

perl -Mbignum -E '
    for(0 .. 1_000_000){
        srand;
        $x=rand; # Random x coordinate
        $y=rand; # Random Y coordinate
        $decision = $x**2 + $y**2 <=1 ? 1:0; # Is this point inside the unit circle?
        $circle += $decision;
        $not_circle += 1-$decision;
        $pi = 4*($circle/($circle+$not_circle)); 
        say $pi
     }'

Note: I first tried it without srand but it got stuck at 3.14 and the digits after that kept oscillating, never converging. This is probably because, after a while the PRNG starts repeating itself. The use of srand will avoid that or at least lengthen the period of the pseudo-random sequence. This is all conjecture, so feel free to correct me if I'm wrong.

  • @Amphiteót Not really sure what is going on there. If it helps my Perl is v5.14.2. I'm not really well-versed with bignum operations in Perl, I'm afraid and I don't know of any particular parts of the above program that require a newer Perl. Anyway, what's interesting about this is the algorithm itself. Try implementing it in your language of choice if this Perl isn't working for you. – Joseph R. Nov 6 '14 at 6:37
  • 1
    @Amphiteót I see. Does the edit solve your problem? – Joseph R. Nov 6 '14 at 7:41
  • @Amphiteót You can try adding ($x,$y,$circle,$not_circle)=(0,0,0); before the loop to make sure all variables are defined before being used. – Joseph R. Nov 6 '14 at 8:05
  • @Amphiteót My mistake. The parens above should have been (0,0,0,0). – Joseph R. Nov 6 '14 at 8:35
  • Re this/5.20.1: Makes sense but didn't see it! Indeed ($x,$y,$circle,$not_circle)=(0,0,0,0). After a minute or two it was hanging around the desired value then it went much closer to 3.1409 before I stopped. Interesting and fun! Thank you! – user44370 Nov 6 '14 at 9:10
2

You can use a spigot algorithm for pi. The following C program by Dik Winter and Achim Flammenkamp will produce the first 15,000 digits of pi, one digit at a time.

a[52514],b,c=52514,d,e,f=1e4,g,h;main(){for(;b=c-=14;h=printf("%04d",e+d/f))for(e=d%=f;g=--b*2;d/=g)d=d*b+f*(h?a[b]:f/5),a[b]=d%--g;}
  • Context: wiki, here and here. – user44370 Nov 6 '14 at 21:42
  • 1
    I love the spigot algorithm for logarithmic constants by Borwein, Bailey and Plouffe, however, this isn't code golf, so may I improve the readability of your code by reformatting it? Also note that BPP-style algorithms can only output digits for pi in bases that are powers of 2, at least without using additional memory. – Franki Nov 7 '14 at 10:22
  • @Franki does formatting the code change the meaning or intention of the post? If not, it should be fine (and the edit can always be rolled back). I don't see how deobfuscating some code could do something else than clarifying. – 11684 Nov 9 '14 at 11:00
  • 1
    @syntaxerror It is to produce exactly 15,000 digits before stopping. The output in the second for-loop produces 4 digits of pi and decrements the mystery number of 52514 by 14. The equation would then be 4*(52514/14) which equals 15004. The last 14 values in the array are ignored to take advantage of fewer tokens to get our exact value of 15000. – Daniel Henneberger Nov 10 '14 at 21:54
  • 1
    @11684 No, it really wouldn't change the meaning or intention of the code. However, I realized this is not a BBP-style spigot algorithm for pi, but another one that someone else has already deobfuscated here stackoverflow.com/a/25837097 – Franki Nov 13 '14 at 16:20
2

PHP

Few examples:

php -r "print pi();"
php -r 'echo M_PI;'
echo "<?=pi();" | php

If you want to change the precision try:

php -d precision=100 -r 'echo pi();'

The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format). [read more]


If you looking for even more accurate precision, check Rosetta Code or Code Golf SE for some programming solutions.

Related: Software that can calculate PI to at least a thousand digits at SR.SE

1

Here's a script that prints pi with the number of digits specified (including '.') by the user.

pi.sh

#!/bin/bash
len=${1:-7}
echo "4*a(1)" | bc -l | cut -c 1-"$len"

output

$ ./pi.sh 10
3.14159265

and with default value:

$ ./pi.sh
3.14159

I've seen people using scale as a bc option, but in my case (bc 1.06.95) this does not output the correct value:

$ echo "scale=5;4*a(1)" | bc -l
3.14156

Notice the last digit.

  • 4
    The question says, "I want to specify how many digits it prints," which, strictly speaking, is ambiguous -- but I think your answer fails (on a technicality) under any reasonable interpretation; your ./pi.sh 10 prints nine digits, counting the initial 3. Also, you're pointing the finger of rounding error, but your ./pi.sh 6 outputs 3.1415, which might not be optimal. – G-Man Says 'Reinstate Monica' Nov 6 '14 at 0:20
  • From memory, the scale=X option of bc will NOT round the number, but simply cut off the number at the X-th decimal digit. – syntaxerror Nov 10 '14 at 20:07
1

I like Abey's answer but did not like how bc was changing the last digit.

echo "scale=5; 4*a(1)" | bc -l
3.14156

So I removed scale used printf to set the number of digits.

printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159
  • Have you noticed, after a scale of 62 digits, they're all 0 whereas this doesn't happen with the original command. – user44370 Nov 6 '14 at 21:48
  • 2
    @Amphiteót, That is because printf has a severe limitation on the floating point numbers in comparison to bc. They are represented by C language double type with precision of about 17 digits so even the non-zero digits after about the 17th one are bogus! ------ I have added an answer with correct rounding of the result not limited by printf. ------ Also to ensure that this command works with various locales you must do something like this: LC_ALL=C printf... – pabouk Nov 7 '14 at 10:04
1

What if you can't for the life of you remember this arctan thing? Or supposing you don't even know this function exists in bc, then try to memorize this simple division:

echo "scale=6; 355 / 113" | bc
3.141592

Will only work for 6 digits, but for non-scientific calculations this will do fine.

If you think you can't remember these two numbers either, write the denominator first, then the numerator:

113 355

Or why not

11 33 55

"double 1, double 3, double 5". All figures are odd. To calculate, split the 6-digit number in half again, and swap denominator and numerator before dividing them. That's about it.

  • As far as I'm concerned, I find 4 * arctan(1) a lot easier to remember that 2 three-digits numbers... I'd easily use 335 instead of 355, or 133 instead of 113. – John WH Smith Nov 9 '14 at 21:12
  • Well, I think it's a matter of personal preference.:) People (like me) who can easily memorize (landline!) phone numbers would be able to memorize two numbers just as one single phone number. It will also help those people who at school felt that trigonometry must've been made by evil powers. – syntaxerror Nov 10 '14 at 20:01
1

It can be assumed that the OP is interested in a short, easy to memorize shell command to print π - but the question does not really say that. This answer is ignoring that assumption and answers the question strictly as written;

Trivial?

While there are 18 answers already, one approach is still missing - and with so many answers, it one could think it't the only one that is missing:
The trivial one: How to print π? Just print π!

That approach seems to be too useless to even think about it, but I will show that it does have it's merrits:

Optimized

We'd normally calculate the value of π. I don't see what's keeping us from optimizing the solution, by precalculating the value - it's a constant, any compiler would do that.

We want some number of digits of π, up to a maximum precision. So we can just take the prefix of the constant, as text:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

A variant with an explicit argument for the precision, eg. for precision 5:

echo 3.1415926535897932384626433832795 | cut -b -$((2+5))
3.14159

Advantages

The maximum precision can be choosen arbitrarily by using a suitable constant calculated using one of the other answers. It is limited only by the maximal length of a command line.
It has constant time complexity for finding the value.
It makes all limits and constraints obvious, based on the low complexity of implementation.
It handles precision larger than the maximum gracefully by returning the constant in the full available precision (with no trailing 0).
So this solution, while trivial, does have advantages. It may be useful when it's used in a shell function, for example.

Minimal

The functionality of the solution above can also be inplemented without creating a process for cut (assuming echo is a shell builtin). It uses the command printf (normally a builtin) in a somewhat obscure way:
The constant is completely handeled as a string (the format uses %s), there is no floating point arithmethic involved, so the limits of float or double do not apply here.
The precision value of the %s escape (5 in the example below) specifies the length of the string prefix to print - which is the precision. The 3. is part of the printf format to keep it out of the precision calculation.

$ printf "3.%.5s\n" 1415926535897932384626433832795 
3.14159

Alternative with precision as separate argument:

$ printf "3.%.*s\n" 5 1415926535897932384626433832795 
3.14159

Or slightly more readable (Note the space between 3. and 14159..., they are separate arguments):

$ printf "%s%.5s\n" 3. 1415926535897932384626433832795
3.14159

Fast

The variant using printf can be expected to be very fast: Because printf is a shell builtin in common shells like bash and zsh, it does not create any processes.
Also, it does not touch any kind of floating point related code, but only manipulation of byte arrays (explicitly not multibyte characters). This is usually faster, often much faster than the use of floating point.

printf compatibility

Often, there are reasons to replace printf by /usr/bin/printf to guarantee consistency or compatibility. In this case, I think we can use the builtin - which is important, as using /usr/bin/printf reduces the "fast" advantage by forking a process.
A common problem with printf compatibility is the number output format depending on the locale. The separating . for numbers can be changed to , based on locale setting; But we do not use numbers, just a string constant containing a literal . - unaffected by locale.
StéphaneChazelas pointed out that printf %.5s works differently in zsh, by counting characters, not bytes as usual. Luckily, our constants use only characters in the lower ASCII-range, which is encoded by one byte per character in any relevant encoding, as long as we use the common UTF-8 encoding for Unicode, and not a fixed width encoding.

  • Note that printf %.5s is char (not byte) based in zsh (sensibly, but against POSIX). ksh93's %.5Ls is graphem based. – Stéphane Chazelas Nov 10 '14 at 22:48

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