跳到内容

kimwalisch/premecount公司

存储库文件导航

素数

生成状态 生成状态 Github发布 C API文档 C++API文档

primecount是一个命令行程序和C/C++库,用于计算素数≤x(最多1031)使用高度优化组合运算的实现素数计数算法.

素数包括所有重要的组合素数算法的实现到目前为止,所有这些都已使用开放式多媒体播放器.primecount包含第一个打开的Deleglise-Rivat算法和Xavier Gourdon算法的源代码实现(有效)。primecount还具有新型负载平衡器它在所有实现中共享,可扩展到数百个CPU内核。素数已经被用来计算几个素数计数函数世界纪录.

安装

primecount命令行程序在一些包管理器中可用。要使用libprimecount进行开发,您可能需要安装libprimecount-dev数据库libprime计数级.

窗户: 翼子板安装素数
macOS: brew安装primecount
Arch Linux: sudo pacman-S素数
Debian/Ubuntu: sudo apt安装primecount
费多拉: sudo dnf安装主计数
免费BSD: pkg安装主计数
开放SUSE: sudo zypper安装primecount

构建说明

您需要安装C++编译器和CMake。理想的素数应该使用GCC或Clang作为这些编译器进行编译支持OpenMP(多线程库)和128位整数。

cmake公司.cmake—构建.--平行sudo cmake--安装.sudo ldconfig

使用示例

#计算素数≤10^14素数1e14#在计算期间打印进度和状态信息素数1e20--状态#使用Meissel算法计算素数素数2**32——梅塞尔#使用4个线程查找10^14素数素数1e14--第n个时间--线程=4--时间

命令行选项

用法:primecount x[选项]计算小于或等于x(<=10^31)的素数。选项:-d、 --使用deleglise-rivat算法的deleglise-rivat计数素数-g、 ——使用Xavier gourdon算法计算gourdon Count素数。这是默认算法。-l、 ——勒让德利用勒让德公式计算素数--使用lehmer公式计算lehmer计数素数--使用Lagarias-Miller-Odlyzko计算lmo素数-m、 --使用meissel公式计算meissel Count素数--李欧拉对数积分函数--Li-inverse使用Li^-1(x)近似第n个素数-n、 --第n次计算第n素数-p、 --primesieve使用埃拉托斯特尼筛对素数进行计数--phi(X,A)计算非可被任何第一个a素数整除-R、 --RiemannR使用Riemann R函数近似pi(x)--RiemannR-逆使用R^-1(x)近似第n素数-s、 --status[=NUM]显示计算进度1%、2%、3%。。。设置小数点后的数字:-s1打印99.9%--test运行各种正确性测试并退出--time以秒为单位打印经过的时间-t、 --threads=NUM设置线程数,1<=NUM<=CPU内核。默认情况下,primecount使用所有可用的CPU内核。-v、 --版本打印版本和许可证信息-h、 --help打印此帮助菜单
高级选项
Deleglise-Rivat算法的高级选项:-a、 --alpha=NUM设置调谐因子:y=x^(1/3)*alpha--P2计算第二部分筛函数--S1计算普通树叶--S2-平凡计算平凡特殊叶--S2-轻松计算轻松特殊树叶--S2-hard计算硬特殊叶子Xavier Gourdon算法的高级选项:--alpha-y=NUM设置调谐因子:y=x^(1/3)*alpha_y--alpha-z=NUM设置调谐因子:z=y*alpha_z--AC计算A+C公式--B计算B公式--D计算D公式--Phi0计算Phi0公式--Sigma计算7 Sigma公式

基准

x个 素数(Prime Count) 勒让德 梅塞尔 拉加里亚斯
米勒
奥德利兹科
解除管制
里瓦
古尔登
1010 455052511 0.01秒 0.01秒 0.01秒 0.01秒 0.00秒
1011 4,118,054,813 0.01秒 0.01秒 0.01秒 0.01秒 0.01秒
1012 37,607,912,018 0.03秒 0.02秒 0.02秒 0.01秒 0.01秒
1013 346,065,536,839 0.09秒 0.06秒 0.03秒 0.02秒 0.03秒
1014 3,204,941,750,802 0.44秒 0.20秒 0.08秒 0.08秒 0.04秒
1015 29,844,570,422,669 2.33秒 0.89秒 0.29秒 0.16秒 0.11秒
1016 279,238,341,033,925 15.49秒 510秒 1.26秒 0.58秒 0.38秒
1017 2623557157654233 127.10秒 39.39秒 5.62秒 2.26秒 1.34秒
1018 24,739,954,287,740,860 1071.14秒 366.93秒 27.19秒 9.96秒 5.35秒
1019 234,057,667,276,344,607 NaN公司 NaN公司 NaN公司 40.93秒 20.16秒
1020 2,220,819,602,560,918,840 NaN公司 NaN公司 NaN公司 167.64秒 81.98秒
1021 21,127,269,486,018,731,928 NaN公司 NaN公司 NaN公司 706.70年代 353.01秒
1022 201,467,286,689,315,906,290 NaN公司 NaN公司 NaN公司 3012.10秒 1350.47秒

上述基准测试在AMD 7R32 CPU(2020年起)上运行,具有16核/32线程时钟频率为3.30GHz。请注意,Jan Büthe references in[11]他计算的$\pi(10^{25})$使用解析素数在40000 CPU核心小时内计数函数算法。Büthe还提到,通过使用zeta函数的运行时可能会减少到4000个CPU核心小时。然而,使用素数和Xavier Gourdon算法$\pi(10^{25})$可以计算AMD Ryzen 3950X CPU仅需460个CPU核心小时!

算法

勒让德公式 $\pi(x)=\pi$
梅塞尔公式 $\pi(x)=\pi(\sqrt[3]{x})+\pi(x,\pi(\sqrt[3]{x}))-\mathrm{P_2}(x,\pi(\sqrt[3]{x}))-1$
莱默公式 $\pi(x)=\pi$
LMO公式 $\pi(x)=\pi$

直到19世纪初,已知最有效的素数计算方法是运行时间为$O(x\log{\log{x}})$操作。第一个对这个界限的改进是勒让德公式(1830),它使用了包含-排除计算x以下素数而不枚举个体的原理素数。Legendre公式的运行时间为O美元(x)$操作和使用$O(\sqrt{x}/\log{x})$空间。1870年,E.D.F.Meissel通过设置$a=\pi(\sqrt[3]{x})$并通过添加修正项$\mathrm{P_2}(x,a)$,梅塞尔公式有运行时间属于$O(x/\log^3{x})$操作和使用$O(\sqrt[3]{x})$空间。1959年D.H.Lehmer扩展了梅塞尔公式,并将运行时间略微提高到$O(x/\log^4{x})$操作和$O(x^{\压裂{3}{8}})$空间。1985年,J.C.Lagarias、V.S.Miller和A.M。Odlyzko发布了一种基于Meissel公式的新算法,该算法运行时间较短复杂性$O(x^{\frac{2}{3}}/\log{x})$操作和仅使用$O(\sqrt[3]{x}\\log^2{x})$空间。

primecount的Legendre、Meissel和Lehmer实现基于汉斯·里塞尔的书[5]它的Lagarias Miller Odlyzko和Deleglise Rivat实现是基于Tomás Oliveira的论文[9]Xavier Gourdon算法的实现基于关于Xavier Gourdon的论文[7].素数计数对所谓的硬特殊叶子的实现是不同的从任何组合中描述的算法目前为止,主要统计论文。而不是使用二进制索引树对于缓存效率很低的计数,primecount使用线性计数器数组与POPCNT指令结合使用缓存效率高且速度快得多。这个硬特产.md文档包含更多信息。素数简单的特殊叶实现及其部分筛选功能实现也包含重大改进。

快速第n素数计算

已知计算第n素数最有效的方法是组合素数计数函数和素数筛。这个想法是近似第n素数,例如使用逆对数积分$\mathrm{Li}^{-1}(n)$或逆Riemann R函数$\mathrm{R}^{-1}(n)$然后使用素数计数函数计算素数,直到这个猜测。完成后,开始筛分(例如,使用Eratostenes),直到找到实际的第n素数。作者已实施素数::nth_prime(n)这种方式(选项:--第n次),它在中找到第n个素数$O(x^{\frac{2}{3}}/\log^2{x})$操作使用$O(\sqrt{x})$空间。

C API(美国石油学会)

包括<素数.h>标头以使用primecount的C API。作为primecount的C API返回的一部分的所有函数-1如果是发生错误并将相应的错误消息打印为标准错误流。

#包括 <素数.h>
#包括 <标准时间>

整数 主要的(){整数64_t 像素 = 素数_pi(1000);打印(“素数<=1000:%ld\n”像素);返回 0;}

C++API

包括<primecount.hpp>标头以使用primecount的C++API。作为primecount的C++API的一部分的所有函数都会抛出一个素数_错误异常(源自标准::异常)万一发生错误。

#包括 <素数.hpp>#包括 <iostream公司>

整数 主要的(){整数64_t像素=素数::pi(1000);标准::cout<<"素数<=1000:"<<pix<<std::endl;返回 0;}

其他语言的绑定

primesieve本机支持C和C++,并具有以下绑定:

通用Lisp: cl-时间计数
朱莉娅: 素数_jll.jl
路易斯安那州: lua-质数
哈斯克尔: 素数手
蟒蛇: 素数
Python语言: 素数-提子
锈蚀: 素数-rs

非常感谢这些绑定的开发人员!