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: http://rosettacode.org/wiki/Pi – Mark Plotnick Nov 05 '14 at 20:30
-
4Note that it gets more fun if you want more digits than around 15. – Thorbjørn Ravn Andersen Nov 06 '14 at 18:41
-
1What do you mean Thorbjørn? – DisplayName Nov 06 '14 at 21:17
-
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 06 '14 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. – keshlam Nov 07 '14 at 05:50
-
1@keshlam : See [How many digits of Pi do you know?](http://forums.xkcd.com/viewtopic.php?f=17&t=4742). FWIW, I memorised the first 100 places of pi several decades ago. :) – PM 2Ring Nov 07 '14 at 14:05
-
1@PM2Ring: A friend of mine knew the square root of two to several thousand places... but as I said, that's a party trick, neither useful for calculation nor for theoretical work. – keshlam Nov 07 '14 at 14:08
-
1@keshlam: I'm glad your friend chose sqrt(2). Pi gets all the publicity, but historically speaking, the humble root 2 is where the whole irrational thing started. :) FWIW, I like to use approximations of sqrt(2) for mental arithmetic (derived from the continued fraction). Sure, memorising ridiculous amounts of digits of these numbers has no practical application, but it's great for your math-nerd street-cred. :) – PM 2Ring Nov 07 '14 at 14:18
-
I should mention a cute π approximation I discovered a couple of years ago: (22/7)*(1-0.0004) = 3.1416, exactly. IOW, you can improve the accuracy of a calculation that uses (22/7) for pi by reducing the result by 0.04%. – PM 2Ring Nov 07 '14 at 14:22
-
If you need help memorizing a random string of digits or something similar, setting it to music can help. The start of Pi can easily be sung to the Mexican Hat Dance, for example...
– keshlam Nov 08 '14 at 14:22 -
Haha, thanks keshlam. In this case i don't need to remember anything. – DisplayName Nov 08 '14 at 14:37
-
Maybe this could be closed? Theres way too many answers already. – DisplayName Nov 08 '14 at 17:28
-
1@DisplayName closing is only done for questions which don't belong here (either off-topic or simply a bad question), not for questions which have too many answers. – Paŭlo Ebermann Nov 09 '14 at 18:26
-
Okay, i have seen questions that are locked because too many people respond. But maybe thats only locked for people below 10 reputation. – DisplayName Nov 09 '14 at 18:28
-
@DisplayName because 15 digits are what native binary representations usually allow. If you need more digits than that your program must switch to another representation without FPU-support which usually is slower. – Thorbjørn Ravn Andersen Nov 10 '14 at 14:53
-
@DisplayName In my book, I think it is a bit unfair to have this closed because so many people have favorited this question, so there *is* a lot of interest. Unfortunately a small oligarchy of 24/7 SE geeks always feel that they have to impose their opinion on the enormously huge rest by these hasty closings. Yes: it's always THE SAME names I read there. Over 5,000 views by now - but 0.1 percent of people dictate a closing. Reminds me of Mozilla developers who always think that what they remove from their software is what their users want to have removed as well. – syntaxerror Nov 11 '14 at 07:39
-
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
-
@terdon do you really think a celebrity like e.g. [Craig Charles](http://www.mirror.co.uk/tv/tv-news/im-celebrity-2014-line-up-craig-4608745) would draw that many views? – Anthon Nov 11 '14 at 19:05
-
Do the digits need to be from the decimal expansion of pi, or would some other number bases be ok? – Franki Nov 13 '14 at 16:23
20 Answers
If you have tex(1) installed:
tex --version | head -1 | cut -f2 -d' '
- 45,310
- 13
- 119
- 114
-
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? – user Nov 05 '14 at 20:26
-
8@MichaelKjörling Actually, it changes to be a more precise approximation of pi. – Abrixas2 Nov 05 '14 at 20:27
-
-
The question asks for control over the number of digits, which this method does not give. – David Richerby Nov 06 '14 at 10:24
-
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 06 '14 at 10:59
-
@DavidRicherby you just have to wait long enough. When Donald Knuth dies the version number of TeX will by definition be \Pi. – Thorbjørn Ravn Andersen Nov 06 '14 at 18:44
-
@ThorbjørnRavnAndersen but this won't print infinite number of digits I guess... – Ruslan Nov 07 '14 at 18:33
-
1@Ruslan depends on the implementation. I would expect in this particular case that it would be done "right". – Thorbjørn Ravn Andersen Nov 07 '14 at 19:13
-
-
(Un)important note: GNOME is at π too at the moment. (v3.14) But Raspberry Pi was obviously quicker ;-) – syntaxerror Nov 11 '14 at 07:46
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)"`. – pabouk - Ukraine stay strong Nov 06 '14 at 09: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. – hobbs Nov 06 '14 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 – Jordan Bentley Nov 06 '14 at 21:04
-
1@JordanBentley, I have added an [answer with correct rounding of the result](http://unix.stackexchange.com/a/166582/19702). – pabouk - Ukraine stay strong Nov 07 '14 at 09:29
-
@hobbs `scale=10000` took 7m26s on my machine. Didn't check valid digits though :) – Ruslan Nov 07 '14 at 18:40
For printing with arbitrary precision, you could use bc and the formula pi = 4*atan(1):
# bc -l
scale=<your precision>
4*a(1)
- 878
- 1
- 5
- 6
-
2There'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 05 '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 05 '14 at 21:14
-
@fduff, I have added an [answer with correct rounding of the result](http://unix.stackexchange.com/a/166582/19702). – pabouk - Ukraine stay strong Nov 07 '14 at 09: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. – DisplayName Nov 05 '14 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 like `pi 300` to print the first 300 digits for example. – terdon Nov 05 '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](https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem#Fermat.27s_conjecture)! – terdon Nov 05 '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? – user Nov 06 '14 at 09: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
- 78,313
- 42
- 165
- 222
-
2This has the additional benefit that it should be reasonably close to O(1) complexity. Or maybe that isn't a benefit after all... – user Nov 05 '14 at 20:53
-
@MichaelKjörling If the OP wants some heavy calculation to test the effectiveness of the CPU fan, that might indeed not be what (s)he wants. – Anthon Nov 05 '14 at 20:55
-
7Also, it's difficult to say that any network interaction is O(1) time complexity in a practical world. :P – HalosGhost Nov 06 '14 at 00: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). – user Nov 06 '14 at 09: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 06 '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). – user Nov 06 '14 at 12:36
-
1Download time can be taken out of the equation by downloading the txt file once: π is not going to change any time soon, is it? – 11684 Nov 09 '14 at 10:51
-
A couple of seconds in python give a million digits `from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)`. – Oct 30 '18 at 09:20
-
@Isaac That doesn't work on Python 3.7: `ModuleNotFoundError: No module named 'mpmath'`. And it is in general nonsensical if you need to download and install something to be able to run a python program where you can download the result you want directly. – Anthon Oct 30 '18 at 10:05
-
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
- 2,360
- 26
- 32
-
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”. – Complicated see bio Nov 10 '14 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
- 79,330
- 30
- 216
- 245
-
For 10.000 digits: Close to 8 minutes in perl, less than 4 in bc. Not the fastest. – Oct 30 '18 at 08:38
With python2:
$ python -c "import math; print(str(math.pi)[:7])"
3.14159
- 9,054
- 6
- 40
- 53
-
4
-
After the edit, with the `(..)` this works in Python 2 and 3. Only seems to have 12 digits. – Anthon Nov 06 '14 at 12:44
-
$ python -c "import math; print(format(math.pi, '.400f'))" 3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 – Artem Shitov Nov 07 '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 08 '14 at 01: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 !!!. – Oct 30 '18 at 09:17
Using Ruby:
require "bigdecimal"
require "bigdecimal/math"
include BigMath
BigDecimal(PI(100)).round(9).to_s("F")
3.141592654
- 71
- 3
-
1One liner: `ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'` – Nov 06 '14 at 00:06
In bash:
$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884
- 181
- 4
-
@Amphiteóth `afmtodit` requires `groff` to be installed. Here on Ubuntu (& flavors), it is *not* standard. JFYI. – syntaxerror Nov 11 '14 at 07: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! – Nov 11 '14 at 07:52
Very simple in PHP using the built in pi() function:
<?php
echo round(pi(), 2);
?>
- 31
- 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 !!!. – Oct 31 '18 at 01: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
- 129
- 5
-
4The shorter `node -e 'console.log(Math.PI)'` is a little better than its best. – chbrown Nov 06 '14 at 04:45
-
1
-
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 Nov 06 '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 06 '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 07 '14 at 13:04
-
@Amphiteóth You can also shorten how long it runs for like this: `node -e 'for(a=0,b=1E7,m=Math,r=m.random;b--;)a+=(1>m.sqrt((c=r())*c+(d=r())*d));console.log(a/.25E7)'`. That will run quickly, but give slightly less accurate results, like `3.14232, 3.140954, 3.1414976, ...` – Paul Nov 07 '14 at 13:05
-
I just edited the `4E8` to `1E7` and the `1E8` to `.25E7` to decrease the running time to 1/40th of it's original time. – Paul Nov 07 '14 at 13:06
-
Thank you, it seems I was impatient with the original command, takes longer on my rig but works! The command you put in the comment above gives me _SyntaxError: Unexpected token ILLEGAL_ with an arrow underneath the "l" of log. Thanks +1 – Nov 07 '14 at 13:14
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.
- 38,849
- 7
- 107
- 143
-
@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 06 '14 at 06: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. – Joseph R. Nov 06 '14 at 08:05
-
@Amphiteót My mistake. The parens above should have been `(0,0,0,0)`. – Joseph R. Nov 06 '14 at 08:35
-
Re [this](https://rt.perl.org/Public/Bug/Display.html?id=119863)/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! – Nov 06 '14 at 09:10
-
-
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
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;}
- 21
- 1
-
Context: [wiki](http://en.wikipedia.org/wiki/Spigot_algorithm), [here](https://cs.uwaterloo.ca/~alopez-o/math-faq/mathtext/node12.html) and [here](http://stackoverflow.com/questions/4084571). – Nov 06 '14 at 21:42
-
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. – Franki Nov 07 '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 09 '14 at 11:00
-
I wish someone could explain how that strange number of 52514 can be explained (ideally a formula). This algorithm is quoted in an uncountable number of pages in the net, but nobody has ever explained why of all numbers it's 52514. And it's no 5-minute job to understand, let alone "break apart" the formulae behind this algorithm. – syntaxerror Nov 10 '14 at 21:11
-
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 Nov 10 '14 at 21:54
-
Thanks! But still I'd like to know how they came up with this number the first place. I suspect a tricky formula. – syntaxerror Nov 11 '14 at 07:31
-
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 http://stackoverflow.com/a/25837097 – Franki Nov 13 '14 at 16:20
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,925
- 4
- 35
- 39
-
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 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 06 '14 at 00: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
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
- 339
- 1
- 2
-
1Have you noticed, after a scale of 62 digits, they're all 0 whereas this doesn't happen with the original command. – Nov 06 '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](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) 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`](http://unix.stackexchange.com/a/166582/19702). ------ Also to ensure that this command works with various locales you must do something like this: `LC_ALL=C printf`... – pabouk - Ukraine stay strong Nov 07 '14 at 10:04
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.
- 16,983
- 5
- 52
- 79
-
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
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.
- 2,236
- 2
- 27
- 49
-
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 09 '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