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.
-
29Take your pick of languages: rosettacode.org/wiki/Pi– Mark PlotnickCommented Nov 5, 2014 at 20:30
-
4Note that it gets more fun if you want more digits than around 15.– Thorbjørn Ravn AndersenCommented Nov 6, 2014 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 ItaliaCommented Nov 6, 2014 at 21:51
-
5My 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.– keshlamCommented Nov 7, 2014 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 ♦Commented Nov 11, 2014 at 13:40
20 Answers
If you have tex(1)
installed:
tex --version | head -1 | cut -f2 -d' '
-
13This 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?– userCommented Nov 5, 2014 at 20:26
-
8@MichaelKjörling Actually, it changes to be a more precise approximation of pi.– Abrixas2Commented Nov 5, 2014 at 20:27
-
@Abrixas2 Yes, I know. With the last version of TeX being version π.– userCommented Nov 5, 2014 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 DCommented Nov 6, 2014 at 10:59 -
1@Ruslan depends on the implementation. I would expect in this particular case that it would be done "right". Commented Nov 7, 2014 at 19:13
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/
-
13Shorter version in
bash
and other shells supporting here strings:bc -l <<< "scale=5; 4*a(1)"
. Commented Nov 6, 2014 at 9:37 -
2
-
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.– hobbsCommented Nov 6, 2014 at 18:18 -
4This 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 Commented Nov 6, 2014 at 21:04
-
1@JordanBentley, I have added an answer with correct rounding of the result. Commented Nov 7, 2014 at 9:29
For printing with arbitrary precision, you could use bc
and the formula pi = 4*atan(1)
:
# bc -l
scale=<your precision>
4*a(1)
-
2There's something funny about the
scale
option,pi = 3.141592..
but withecho "scale=5; 4*a(1)" | bc -l => 3.14156
I would then expect to see3.14159
?– fduffCommented Nov 5, 2014 at 21:10 -
7
scale
specifies the precision to use for calculation, so withscale=5
, no operation will use more than five fractional digits for any atomic operation.– Abrixas2Commented Nov 5, 2014 at 21:14 -
@fduff, I have added an answer with correct rounding of the result. Commented Nov 7, 2014 at 9:30
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).
$ ./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
FedoraOn 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 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. Commented Nov 5, 2014 at 20:28
-
2
-
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 likepi 300
to print the first 300 digits for example.– terdon ♦Commented Nov 5, 2014 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 ♦Commented Nov 5, 2014 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?– userCommented Nov 6, 2014 at 9:40
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
-
2This has the additional benefit that it should be reasonably close to O(1) complexity. Or maybe that isn't a benefit after all...– userCommented Nov 5, 2014 at 20:53
-
7Also, it's difficult to say that any network interaction is O(1) time complexity in a practical world. :P Commented Nov 6, 2014 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).– userCommented Nov 6, 2014 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). Commented Nov 6, 2014 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).– userCommented Nov 6, 2014 at 12:36
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 better 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
-
2Computing 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”. Commented Nov 10, 2014 at 17:59
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.– user232326Commented Oct 30, 2018 at 8:38
With python2:
$ python -c "import math; print(str(math.pi)[:7])"
3.14159
-
4For completeness's sake, this solution is python2-specific. Commented Nov 5, 2014 at 22:36
-
After the edit, with the
(..)
this works in Python 2 and 3. Only seems to have 12 digits.– AnthonCommented Nov 6, 2014 at 12:44 -
$ python -c "import math; print(format(math.pi, '.400f'))" 3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Commented Nov 7, 2014 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])"
Commented Nov 8, 2014 at 1:15 -
1The 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 !!!.– user232326Commented Oct 30, 2018 at 9:17
Using Ruby:
require "bigdecimal"
require "bigdecimal/math"
include BigMath
BigDecimal(PI(100)).round(9).to_s("F")
3.141592654
-
1One liner:
ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'
– user44370Commented Nov 6, 2014 at 0:06
In bash:
$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884
-
@Amphiteóth
afmtodit
requiresgroff
to be installed. Here on Ubuntu (& flavors), it is not standard. JFYI. Commented Nov 11, 2014 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!– user44370Commented Nov 11, 2014 at 7:52
Very simple in PHP using the built in pi() function:
<?php
echo round(pi(), 2);
?>
-
1
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 !!!.– user232326Commented Oct 31, 2018 at 1:22
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
-
4The shorter
node -e 'console.log(Math.PI)'
is a little better than its best.– chbrownCommented Nov 6, 2014 at 4:45 -
1@chbrown That doesn't satisfy the OPs "not serious" requirement.– PaulCommented Nov 6, 2014 at 12:55
-
1What "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 ♦Commented Nov 6, 2014 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. Commented Nov 6, 2014 at 16:08
-
@Amphiteóth It takes about 20 seconds to run on my computer. You might just need to give it some time.– PaulCommented Nov 7, 2014 at 13:04
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. Commented Nov 6, 2014 at 6:37 -
1
-
@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. Commented Nov 6, 2014 at 8:05 -
@Amphiteót My mistake. The parens above should have been
(0,0,0,0)
. Commented Nov 6, 2014 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!– user44370Commented Nov 6, 2014 at 9:10
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;}
-
-
2I 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.– FrankiCommented Nov 7, 2014 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.– 11684Commented Nov 9, 2014 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.– DanielCommented Nov 10, 2014 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– FrankiCommented Nov 13, 2014 at 16:20
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
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.
-
4The 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 initial3
. Also, you're pointing the finger of rounding error, but your./pi.sh 6
outputs3.1415
, which might not be optimal. Commented Nov 6, 2014 at 0:20 -
From memory, the
scale=X
option ofbc
will NOT round the number, but simply cut off the number at the X-th decimal digit. Commented Nov 10, 2014 at 20:07
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
-
1Have you noticed, after a scale of 62 digits, they're all 0 whereas this doesn't happen with the original command.– user44370Commented Nov 6, 2014 at 21:48
-
2@Amphiteót, That is because
printf
has a severe limitation on the floating point numbers in comparison tobc
. They are represented by C languagedouble
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 byprintf
. ------ Also to ensure that this command works with various locales you must do something like this:LC_ALL=C printf
... Commented Nov 7, 2014 at 10:04
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. Commented Nov 9, 2014 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. Commented Nov 10, 2014 at 20:01
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. Commented Nov 10, 2014 at 22:48