multiprecision/doc/html/boost_multiprecision/tut/primetest.html
2019-10-17 16:29:54 +01:00

118 lines
14 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Primality Testing</title>
<link rel="stylesheet" href="../../multiprecision.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Chapter&#160;1.&#160;Boost.Multiprecision">
<link rel="up" href="../tut.html" title="Tutorial">
<link rel="prev" href="random.html" title="Generating Random Numbers">
<link rel="next" href="lits.html" title="Literal Types and constexpr Support">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="random.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tut.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="lits.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_multiprecision.tut.primetest"></a><a class="link" href="primetest.html" title="Primality Testing">Primality Testing</a>
</h3></div></div></div>
<p>
The library implements a Miller-Rabin test for primality:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">miller_rabin</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">expression_template_option</span> <span class="identifier">ExpressionTemplates</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Engine</span><span class="special">&gt;</span>
<span class="keyword">bool</span> <span class="identifier">miller_rabin_test</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;&amp;</span> <span class="identifier">n</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">trials</span><span class="special">,</span> <span class="identifier">Engine</span><span class="special">&amp;</span> <span class="identifier">gen</span><span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">expression_template_option</span> <span class="identifier">ExpressionTemplates</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Engine</span><span class="special">&gt;</span>
<span class="keyword">bool</span> <span class="identifier">miller_rabin_test</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">Backend</span><span class="special">,</span> <span class="identifier">ExpressionTemplates</span><span class="special">&gt;&amp;</span> <span class="identifier">n</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="identifier">trials</span><span class="special">);</span>
</pre>
<p>
These functions perform a Miller-Rabin test for primality, if the result
is <code class="computeroutput"><span class="keyword">false</span></code> then <span class="emphasis"><em>n</em></span>
is definitely composite, while if the result is true then n is probably prime.
The probability to declare a composite n as probable prime is at most 0.25<sup>trials</sup>.
Note that this does not allow a statement about the probability of n being
actually prime (for that, the prior probability would have to be known).
The algorithm used performs some trial divisions to exclude small prime factors,
does one Fermat test to exclude many more composites, and then uses the Miller-Rabin
algorithm straight out of Knuth Vol 2, which recommends 25 trials for a pretty
strong likelihood that <span class="emphasis"><em>n</em></span> is prime.
</p>
<p>
The third optional argument is for a Uniform Random Number Generator from
Boost.Random. When not provided the <code class="computeroutput"><span class="identifier">mt19937</span></code>
generator is used. Note that when producing random primes then you should
probably use a different random number generator to produce candidate prime
numbers for testing, than is used internally by <code class="computeroutput"><span class="identifier">miller_rabin_test</span></code>
for determining whether the value is prime. It also helps of course to seed
the generators with some source of randomness.
</p>
<p>
The following example searches for a prime <code class="computeroutput"><span class="identifier">p</span></code>
for which <code class="computeroutput"><span class="special">(</span><span class="identifier">p</span><span class="special">-</span><span class="number">1</span><span class="special">)/</span><span class="number">2</span></code> is also probably prime:
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">cpp_int</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">multiprecision</span><span class="special">/</span><span class="identifier">miller_rabin</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iomanip</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">random</span><span class="special">;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">cpp_int</span> <span class="identifier">int_type</span><span class="special">;</span>
<span class="identifier">mt11213b</span> <span class="identifier">base_gen</span><span class="special">(</span><span class="identifier">clock</span><span class="special">());</span>
<span class="identifier">independent_bits_engine</span><span class="special">&lt;</span><span class="identifier">mt11213b</span><span class="special">,</span> <span class="number">256</span><span class="special">,</span> <span class="identifier">int_type</span><span class="special">&gt;</span> <span class="identifier">gen</span><span class="special">(</span><span class="identifier">base_gen</span><span class="special">);</span>
<span class="comment">//</span>
<span class="comment">// We must use a different generator for the tests and number generation, otherwise</span>
<span class="comment">// we get false positives.</span>
<span class="comment">//</span>
<span class="identifier">mt19937</span> <span class="identifier">gen2</span><span class="special">(</span><span class="identifier">clock</span><span class="special">());</span>
<span class="keyword">for</span><span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">100000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">int_type</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">gen</span><span class="special">();</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">miller_rabin_test</span><span class="special">(</span><span class="identifier">n</span><span class="special">,</span> <span class="number">25</span><span class="special">,</span> <span class="identifier">gen2</span><span class="special">))</span>
<span class="special">{</span>
<span class="comment">// Value n is probably prime, see if (n-1)/2 is also prime:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"We have a probable prime with value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showbase</span> <span class="special">&lt;&lt;</span> <span class="identifier">n</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">miller_rabin_test</span><span class="special">((</span><span class="identifier">n</span><span class="special">-</span><span class="number">1</span><span class="special">)/</span><span class="number">2</span><span class="special">,</span> <span class="number">25</span><span class="special">,</span> <span class="identifier">gen2</span><span class="special">))</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"We have a safe prime with value: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showbase</span> <span class="special">&lt;&lt;</span> <span class="identifier">n</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Ooops, no safe primes were found - probably a bad choice of seed values!"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2019 John Maddock
and Christopher Kormanyos<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="random.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tut.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="lits.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>