如何打印pi(3.14159)?[关闭]


35

什么命令可以为我打印pi?我想指定它可以打印多少个数字,但我在网上找不到任何东西。我只希望能够打印pi。



4
请注意,如果您想要的位数多于15,它会变得更加有趣。
ThorbjørnRavn Andersen 2014年

2
@DisplayName:这意味着您将无法再使用任何使用双精度浮点值(通常是大多数语言中可用的最高精度“内置” FP数据类型)在内部存储/计算PI的程序。
Matteo Italia

5
我的解决方案是在几十年前才由语言库提供的,它是将它记忆在比我使用的浮点数更多的位置上:3.1415926535897932384626通常足够接近于实际用途,甚至是最不切实际的用途-任何真实的东西-world与其他数字相比,它将有更多的错误,并且从理论上讲,我将坚持使用符号而不是数字值。
keshlam 2014年

3
@syntaxerror的兴趣无关紧要。如果您要发布一个问题,要求提供名人的裸照,那么它将获得成千上万的观看次数,并且很有可能遭到投票。但这并没有成为话题。这个问题是一个过于广泛的经典例子。只看答案的数量。还应注意,OP没有指定任何限制,这使得可能的答案基本上是无限的。无论如何,关闭并不是删除。该问题及其所有23个答案仍将在此处。结束只是意味着不再接受任何答案。我们真的需要更多的方法来打印π吗?
terdon

Answers:


52

您可以使用以下命令:

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

其中scale是小数点后的位数。

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


12
在较短的版本bash和另一个外壳在这里支持字符串:bc -l <<< "scale=5; 4*a(1)"
pabouk 2014年

2
我不知道这可以走几位数?
DisplayName

4
@DisplayName相当多。scale=1000会很快给出999个正确的数字(最后一位数字减去1,这是合理的,因为我们正在计算pi / 4,然后乘以4)。scale=4000在几秒钟内给出4000个正确的数字。scale=10000花费的时间比我的耐心要长,但可能会提供9999或10000个正确的数字。
hobbs 2014年

4
这会在我的机器上输入“ echo“ scale = 5; 4 * a(1)” |给我的机器带来错误的结果。bc -l'返回3.14156,最后一位数字应为9
Jordan Bentley

1
@JordanBentley,我添加了一个答案,并正确舍入了结果
pabouk

61

如果已tex(1)安装:

tex --version | head -1 | cut -f2 -d' '

13
仅出于机灵,这几乎是值得赞扬的。虽然在升级软件包时此输出会更改。我们应该认为这是功能还是错误?
2014年

8
@MichaelKjörling实际上,它更改为pi的更精确近似值。
Abrixas2 2014年

@ Abrixas2是的,我知道。TeX的最新版本是π版本。
2014年

30
@DavidRicherby可以通过另外调用来打印更少的数字cut。等待很长时间然后再次运行命令,可以打印更多的数字。
史蒂文D

1
@Ruslan取决于实现。我希望在这种特殊情况下,它会“正确”地完成。
托尔比约恩Ravn的安徒生

23

对于任意精度的打印,可以使用bc和公式pi = 4*atan(1)

# bc -l
scale=<your precision>
4*a(1)

2
这个选项有些有趣scalepi = 3.141592..但是echo "scale=5; 4*a(1)" | bc -l => 3.14156我希望看到3.14159
fduff 2014年

7
scale指定用于计算的精度,因此使用时scale=5,任何原子操作都不会使用超过5个小数位。
Abrixas2 2014年

@fduff,我添加了一个对结果正确舍入答案
pabouk 2014年

20

如果您想要某种可以计算π值的东西那么有几种方法。也许最明显的解决方案是使用现成的软件包,例如pi(Debian软件包链接),如果要信任Debian的软件包描述,可以将该值计算为任意精度,并且仅受内存限制。

pi实际上是CLN库(数字类库)附带的一个示例。它包括一些示例应用程序,这些应用程序提供了用于生成任意长度的数字(例如Pi,Fibonacci等)的工具。CLN软件包可预先打包在Debian / Ubuntu中(这就是上面的Debian链接所指向的)。

例子
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

注意:这些示例的来源在此处位于CLN代码库的来源中

其他发行

软呢帽

在Fedora上,我必须下载源tarball并自行构建,但构建时很少大惊小怪。不论出于何种原因cln,Fedora上的软件包仅包含库,而忽略了Debian / Ubuntu版本中可用的示例(上述)。

拱提供在同一个程序cln(感谢Amphiteót)。


是的,他是说我输入的总价值是我脑海中所拥有的。
DisplayName 2014年

2
“总价值”?那是什么意思...?
凯尔·斯特兰德

2
@DisplayName读取其余答案。专用程序pi听起来像您想要的东西。例如,您可以执行pi 300打印前300位数的操作。
terdon

3
@KyleStrand我发现了一个真正奇妙的答案,这个评论太狭窄了而无法包含。嘿,对Fermat有用
terdon

我很想知道为什么这得到了两次否决。投票否决的人在认为答案没有用之前没有读过答案吗?
2014年

17

对于最多一百万个数字,您可以使用以下内容(此处为3000个数字):

curl --silent http://www.angio.net/pi/digits/pi1000000.txt | cut -c1-3000

2
这具有额外的好处,即它应该合理地接近O(1)的复杂度。也许这毕竟不是好处……
CVn 2014年

7
同样,很难说任何网络交互在现实世界中都是O(1)时间复杂性。:P
HalosGhost 2014年

2
@HalosGhost出于我们的目的(与每次计算pi的n位数字相比),通过网络从特定服务器下载固定数量的数据可能实际上是 O(1),而计算pi的n位数字可能是有效的。至少是O(log n)之类的东西,甚至可能更高(我对那些算法不熟悉)。数据的实际下载可能比开始下载的开销花费更多的时间,因此,在合理固定的数据传输速率的情况下,下载时间占主导,并且您到达O(1)附近。因此,O(1)。
2014年

4
@MichaelKjörling当您说O(1)时,您实际上不是在说O(n)吗?下载时间以线性形式(所需数字位数),因此为O(n)。
CodesInChaos

1
@CodesInChaos不,下载时间是恒定的(考虑到恒定的传输速率),因为您正在下载恒定数量的数字(此处为一百万)。除非(在这种特定情况下)卷曲在下载时足够聪明以至于可以在下载时进行打印,并且在由于cut退出而导致管道中断后停止下载?如果是这样,我同意,它将是O(n)。
2014年

15

其他一些答案在输出的最后位置显示不正确的数字。以下是使用的变体答案,bc但结果正确舍入。该变量s包含有效位数(包括3小数点前)。

四舍五入

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

四舍五入(截断)

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

四舍五入说明

舍入直接在中执行bc。这不受命令的限制,该命令printf使用C语言double类型表示形式表示数字,其精度约为17个有效数字。四舍五入答案printf

scale=s-1设置要截断的位数。pi/1将结果除以1以应用截断。简单pi不会截断数字。

四舍五入需要将要截断的第一个数字加5(5×10 -s),以便在数字高等于5的情况下,将保留的最后一个数字递增。

霍布斯测试看来,scale=s+2即使很长的数字,也将四舍五入/舍去的另外三个数字()就足够了。

在这里串

上面的例子在这里的字符串,其支持例如bashkshzsh。如果您的外壳不支持此处,请使用字符串echo和管道代替:

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

2
正如您在评论中所声称的那样,为舍入目的计算另外三个数字并不是“正确的舍入”。首先,您对计算错误没有任何限制。如果可以按fduff的要求在最后3个单元中出错,那么为什么在最后1000个单元中不出错呢?其次,请参阅“制表者的困境”。
复杂,请参见

12

perl一行(使用bignum):

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

例如

perl -Mbignum=bpi -wle 'print bpi(6)'
3.14159

10.000位数字:Perl中将近8分钟,而公元前少于4分钟。不是最快的。
艾萨克(Isaac)

9

使用python2:

$ python -c "import math; print(str(math.pi)[:7])"
3.14159

4
为了完整起见,此解决方案是python2特定的。
HalosGhost 2014年

编辑后,使用(..)此功能可在Python 2和3中使用。似乎只有12位数字。
Anthon 2014年

$蟒蛇-c “进口数学;打印(格式(math.pi, '.400f'))” 3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
阿尔乔姆Shitov

1
@ArtemShitov -我的坏,尝试导入gmpy2(如果您有它安装)python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])"。提高精度以获取更多数字...例如python -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
don_crissti 2014年

1
我能找到的最快速度from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)只有几秒钟,达到一百万个数字。一点也不差 !!!。
艾萨克(Isaac)

7

使用Ruby:

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

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

3.141592654

1
一个班轮:ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'

4

在bash中:

$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884

@Amphiteóth afmtodit需要groff安装。在Ubuntu(&flavor)上,它不是标准的。JFYI。
语法错误

@syntaxerror谢谢,很好!我已经删除了我的例子。我的意思是,当读取此AI grep在我的系统上运行时,便在多个位置搜索了该常数。这就是为什么这对我来说是+1!


3

我怎么想念这个问题...

是我几个星期前在Stack Overflow上发布的Python pi程序。它的速度不是特别快,但是可以做很多数字。:)但是,正如我在该线程中提到的那样,我通常使用Python的mpmath模块进行任意精度算术,而mpmath具有相当快的pi生成器。

例如,

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

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

恕我直言,考虑到它运行在具有单核2GHz处理器,2 GB RAM并写入旧的IDE驱动器的计算机上,在5秒内提供500000位小数的pi并不是太过分。


尝试from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)在两秒内(在pip3安装了mpmath之后)输入一百万个数字。一点也不差 !!!。
艾萨克(Isaac)

2

如果已node.js安装,这将为您找到pi尽最大努力,尽管它的最佳表现不是很好:

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)'

样本输出:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371

4
较短的node -e 'console.log(Math.PI)'总比最好的要好。
chbrown 2014年

1
@chbrown不满足OP“不严重”的要求。
保罗

1
什么是“不严重”的要求?OP只是说他们是在找乐子,而不是想要某种“不认真”的答案。那到底是什么意思呢?像echo pie什么?
terdon

我输入的内容是因为当您问问题时,有时人们会说“这不是脚本编写工厂”,所以我说,因为没有真正的原因,我只想知道如何打印pi。
DisplayName 2014年

@Amphiteóth在我的计算机上运行大约需要20秒。您可能只需要花一些时间。
保罗

2

蒙特卡罗方法

参见,例如,对于本方法的说明。

注意事项

  • 不够准确
  • 花费很长时间才能融合到任何有用的东西

好处

好玩:-)

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
     }'

注意:我首先尝试了一下,srand但没有卡住,3.14之后的数字一直在振荡,从未收敛。这可能是因为一段时间后PRNG开始重复其自身。使用srand可以避免或至少延长伪随机序列的周期。这都是推测,所以如果我错了,请随时纠正我。


@Amphiteót不太确定那里发生了什么。如果有帮助,我的Perl是v5.14.2。恐怕我不太熟悉bignumPerl的操作,而且我不知道上述程序中需要更新的Perl的任何特定部分。无论如何,有趣的是算法本身。如果该Perl不适合您,请尝试以您选择的语言实现它。
Joseph R.

1
@Amphiteót我明白了。编辑是否解决了您的问题?
约瑟夫R.14年

@Amphiteót您可以尝试($x,$y,$circle,$not_circle)=(0,0,0);在循环之前添加,以确保在使用之前定义了所有变量。
约瑟夫R.14年

@Amphiteót我的错。上面的括号应该是(0,0,0,0)
约瑟夫R.14年

Re this /5.20.1:有意义,但没有看到!的确($x,$y,$circle,$not_circle)=(0,0,0,0)。一两分钟后,它徘徊在所需的值附近,然后在我停下之前,它更接近于3.1409。有趣而有趣!谢谢!

2

您可以对pi使用spigot算法。Dik Winter和Achim Flammenkamp编写的以下C程序将生成pi的前15,000位,一次生成一位。

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;}

上下文:Wiki此处此处

1
我喜欢Borwein,Bailey和Plouffe的对数常量的自定义算法,但是,这不是代码问题,所以我可以通过重新格式化来提高代码的可读性吗?还要注意,BPP风格的算法只能以2的幂为单位输出pi的数字,至少不使用额外的内存。
Franki 2014年

@Franki格式化代码会改变帖子的含义或意图吗?如果不是,那应该没问题(并且编辑总是可以回滚)。我看不到对代码进行模糊处理除了澄清之外还可以做其他事情。
2014年

1
@syntaxerror它将在停止之前精确地产生15,000位数字。第二个for循环中的输出产生pi的4位数字,并将52514的奥秘数减14。然后,等式为4 *(52514/14),等于15004。将忽略数组中的最后14个值以取利用较少的令牌来获得15000的我们的精确值
丹尼尔Henneberger

1
@ 11684不,它真的不会改变代码的含义或意图。但是,我意识到这不是针对pi的BBP样式的插口算法,而是另一种已在此处进行混淆的算法stackoverflow.com/a/25837097
Franki 2014年

2

的PHP

几个例子:

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

如果要更改精度,请尝试:

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

浮点数的大小取决于平台,尽管通常值(64位IEEE格式)的最大值约为1.8e308,精度约为14个十进制数字。[阅读更多]


如果您想要更精确的精度,请查看Rosetta CodeCode Golf SE以获取一些编程解决方案。

相关:可以在SR.SE上计算PI至少为一千位数的软件


1

这是一个脚本,该脚本以用户指定的位数(包括“。”)打印pi。

sh

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

输出

$ ./pi.sh 10
3.14159265

并使用默认值:

$ ./pi.sh
3.14159

我见过人们使用它scale作为bc选项,但是在我的情况下(bc 1.06.95),它不会输出正确的值:

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

注意最后一位。


4
问题是:“我想指定要打印多少位数字,”严格来说,这是模棱两可的,但我认为您的回答在某种合理的解释下(以技术性而言)是失败的;您的./pi.sh 10印刷品会以九位数显示,并以开头计算3。另外,您指的是四舍五入误差,但是您的./pi.sh 6output 3.1415可能不是最佳的。
G-Man说'Resstate Monica'2014/

从内存中,scale=X选项bc不会舍入数字,而只是截断第X个十进制数字。
2014年

1

我喜欢Abey的回答,但不喜欢BC如何更改最后一位数字。

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

因此,我删除了使用printf设置的数字位数。

printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159

您是否注意到,在62位小数位数之后,它们全为0,而原来的命令则不会发生这种情况。

2
@Amphiteót,这是因为printf与相比,浮点数受到严格限制bc。它们由C语言double类型表示 ,精度约为17位数字,因此,即使 17 位之后的非零数字也是伪造的!------我添加了一个答案,正确舍入了结果,不受限制printf。------同样,要确保此命令可以在各种语言环境下工作,您必须执行以下操作:LC_ALL=C printf...
pabouk 2014年

1

如果您一生都不记得该arctan怎么办?或者假设您甚至都不知道该函数存在于中bc,然后尝试记住这个简单的除法:

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

仅适用于6位数字,但对于非科学计算,则可以正常工作。

如果您认为自己也不记得这两个数字,请先写分母,然后写分子:

113355

还是为什么不

11 33 55

“双1,双3,双5”。所有数字都是奇怪的。要进行计算,请将6位数字再对半分割,并在除以分母和分子之前将其交换。就是这样


就我而言,我发现4 * arctan(1)一个更容易记住2三位号码......我会轻松地使用335,而不是355或133,而不是113
约翰·史密斯WH

好吧,我认为这是个人喜好问题。:)像我一样容易记住(固定电话!)电话号码的人将能够记住两个数字,就像一个电话号码一样。它还将帮助那些在学校觉得三角学一定是由邪恶力量造就的人们。
语法错误

1

可以假定OP对一个简短,易于记忆的shell命令打印π感兴趣-但问题并没有真正说明这一点。这个答案忽略了这个假设,严格按照书面回答了这个问题。

不重要的?

虽然已经有18个答案,但仍然缺少一种方法-答案如此之多,它可能会认为不是唯一一个缺少的方法:
琐碎的方法:如何打印π?只需打印π!

这种方法似乎根本没用,甚至无法考虑,但我将证明它确实有其优点:

优化

通常,我们将计算π的值。我看不出是什么让我们无法通过预先计算值来优化解决方案的,因为它是一个常数,任何编译器都可以做到这一点。

我们需要一定数量的π,但要达到最大精度。因此,我们可以将常量的前缀作为文本:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

带有显式参数精度的变体,例如。为了精度5

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

好处

可以通过使用其他答案之一计算出的合适常数来任意选择最大精度。它仅受命令行最大长度的限制。
查找值具有恒定的时间复杂度。
基于实施的低复杂性,它使所有限制和约束显而易见。
它以完全可用的精度返回常量(不带尾部0),从而优雅地处理大于最大值的精度。
因此,这种解决方案虽然很简单,但确实具有优势。例如,当它在shell函数中使用时,它可能会很有用。

最小的

上面的解决方案的功能也可以在不创建过程的情况下进行补充cut(假设echo是内置的shell)。它printf以某种模糊的方式使用命令(通常是内置
函数):常数完全作为字符串处理(格式使用%s),不涉及浮点运算,因此此处的限制floatdouble不适用。转义
的精度值%s5在下面的示例中)指定要打印的字符串前缀的长度-这是精度。该3.是部分printf格式,以保持它的精确计算。

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

精度作为单独参数的替代方案:

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

或者稍微更易读(注之间的空间3.14159...,它们是独立的参数):

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

快速

printf可以预料到,使用这种变体的速度非常快:因为printf是在像shell bash和shell这样的通用shell中内置的shell zsh,它不会创建任何进程。
同样,它不涉及任何与浮点相关的代码,而仅涉及字节数组的操作(显式不是多字节字符)。这通常比使用浮点更快,通常更快。

printf兼容性

通常情况下,我们有理由取代 printf/usr/bin/printf,以保证一致性和兼容性。在这种情况下,我认为我们可以使用内建函数-这很重要,因为使用内建函数/usr/bin/printf会通过分叉进程来降低“快速”优势。兼容性
的常见问题printf是数字输出格式取决于语言环境。.可以,根据区域设置将数字分隔更改为;但是我们不使用数字,而只使用包含文字的字符串常量.-不受语言环境的影响。
StéphaneChazelas指出printf %.5szsh,通过计算字符(而不是通常的字节)来计算。幸运的是,我们的常量仅使用较低ASCII范围内的字符,只要我们UTF-8对Unicode 使用通用编码,而不使用固定宽度编码,则在任何相关编码中每个字符每个字节用一个字节编码。


请注意,这printf %.5s是基于zsh的char(不是字节)(明智地,但针对POSIX)。ksh93%.5Ls是基于字素的。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.