Merge pull request #11 from NAThompson/develop

Modular exponentiation, modular multiplicative inverse
This commit is contained in:
Andrey Semashev
2018-11-03 22:46:30 +03:00
committed by GitHub
20 changed files with 865 additions and 232 deletions

View File

@ -15,7 +15,7 @@ programming problems.
namespace boost
{
namespace math
namespace integer
{
template < typename IntegerType >
@ -53,10 +53,10 @@ programming problems.
[section GCD Function Object]
[*Header: ] [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>]
[*Header: ] [@../../../../boost/integer/common_factor_rt.hpp <boost/integer/common_factor_rt.hpp>]
template < typename IntegerType >
class boost::math::gcd_evaluator
class boost::integer::gcd_evaluator
{
public:
// Types
@ -70,7 +70,7 @@ programming problems.
second_argument_type const &b ) const;
};
The boost::math::gcd_evaluator class template defines a function object
The boost::integer::gcd_evaluator class template defines a function object
class to return the greatest common divisor of two integers.
The template is parameterized by a single type, called IntegerType here.
This type should be a numeric type that represents integers.
@ -89,10 +89,10 @@ They are also declared `noexcept` when appropriate.
[section LCM Function Object]
[*Header: ] [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>]
[*Header: ] [@../../../../boost/integer/common_factor_rt.hpp <boost/integer/common_factor_rt.hpp>]
template < typename IntegerType >
class boost::math::lcm_evaluator
class boost::integer::lcm_evaluator
{
public:
// Types
@ -106,7 +106,7 @@ They are also declared `noexcept` when appropriate.
second_argument_type const &b ) const;
};
The boost::math::lcm_evaluator class template defines a function object
The boost::integer::lcm_evaluator class template defines a function object
class to return the least common multiple of two integers. The template
is parameterized by a single type, called IntegerType here. This type
should be a numeric type that represents integers. The result of the
@ -126,13 +126,13 @@ They are also declared `noexcept` when appropriate.
[section:run_time Run-time GCD & LCM Determination]
[*Header: ] [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>]
[*Header: ] [@../../../../boost/integer/common_factor_rt.hpp <boost/integer/common_factor_rt.hpp>]
template < typename IntegerType >
constexpr IntegerType boost::math::gcd( IntegerType const &a, IntegerType const &b );
constexpr IntegerType boost::integer::gcd( IntegerType const &a, IntegerType const &b );
template < typename IntegerType >
constexpr IntegerType boost::math::lcm( IntegerType const &a, IntegerType const &b );
constexpr IntegerType boost::integer::lcm( IntegerType const &a, IntegerType const &b );
template < typename IntegerType, typename... Args >
constexpr IntegerType gcd( IntegerType const &a, IntegerType const &b, Args const&... );
@ -148,16 +148,16 @@ They are also declared `noexcept` when appropriate.
std::pair<typename std::iterator_traits<I>::value_type, I>
lcm_range(I first, I last);
The boost::math::gcd function template returns the greatest common
The boost::integer::gcd function template returns the greatest common
(nonnegative) divisor of the two integers passed to it.
`boost::math::gcd_range` is the iteration of the above gcd algorithm over a
`boost::integer::gcd_range` is the iteration of the above gcd algorithm over a
range, returning the greatest common divisor of all the elements. The algorithm
terminates when the gcd reaches unity or the end of the range. Thus it also
returns the iterator after the last element inspected because this may not be
equal to the end of the range. The variadic version of `gcd` behaves similarly
but does not indicate which input value caused the gcd to reach unity.
The boost::math::lcm function template returns the least common
The boost::integer::lcm function template returns the least common
(nonnegative) multiple of the two integers passed to it.
As with gcd, there are range and variadic versions of the function for
more than 2 arguments.
@ -171,17 +171,17 @@ They are also declared `noexcept` when appropriate.
[note These functions are deprecated in favor of constexpr `gcd` and `lcm` on C++14 capable compilers.]
[*Header: ] [@../../../../boost/math/common_factor_ct.hpp <boost/math/common_factor_ct.hpp>]
[*Header: ] [@../../../../boost/integer/common_factor_ct.hpp <boost/integer/common_factor_ct.hpp>]
typedef ``['unspecified]`` static_gcd_type;
template < static_gcd_type Value1, static_gcd_type Value2 >
struct boost::math::static_gcd : public mpl::integral_c<static_gcd_type, implementation_defined>
struct boost::integer::static_gcd : public mpl::integral_c<static_gcd_type, implementation_defined>
{
};
template < static_gcd_type Value1, static_gcd_type Value2 >
struct boost::math::static_lcm : public mpl::integral_c<static_gcd_type, implementation_defined>
struct boost::integer::static_lcm : public mpl::integral_c<static_gcd_type, implementation_defined>
{
};
@ -190,7 +190,7 @@ for use in integral-constant-expressions by the compiler. Usually this
the same type as `boost::uintmax_t`, but may fall back to being `unsigned long`
for some older compilers.
The boost::math::static_gcd and boost::math::static_lcm class templates
The boost::integer::static_gcd and boost::integer::static_lcm class templates
take two value-based template parameters of the ['static_gcd_type] type
and inherit from the type `boost::mpl::integral_c`.
Inherited from the base class, they have a member /value/
@ -201,7 +201,7 @@ is beyond the range of `static_gcd_type`.
[h3 Example]
#include <boost/math/common_factor.hpp>
#include <boost/integer/common_factor.hpp>
#include <algorithm>
#include <iterator>
#include <iostream>
@ -212,28 +212,28 @@ is beyond the range of `static_gcd_type`.
using std::endl;
cout << "The GCD and LCM of 6 and 15 are "
<< boost::math::gcd(6, 15) << " and "
<< boost::math::lcm(6, 15) << ", respectively."
<< boost::integer::gcd(6, 15) << " and "
<< boost::integer::lcm(6, 15) << ", respectively."
<< endl;
cout << "The GCD and LCM of 8 and 9 are "
<< boost::math::static_gcd<8, 9>::value
<< boost::integer::static_gcd<8, 9>::value
<< " and "
<< boost::math::static_lcm<8, 9>::value
<< boost::integer::static_lcm<8, 9>::value
<< ", respectively." << endl;
int a[] = { 4, 5, 6 }, b[] = { 7, 8, 9 }, c[3];
std::transform( a, a + 3, b, c, boost::math::gcd_evaluator<int>() );
std::transform( a, a + 3, b, c, boost::integer::gcd_evaluator<int>() );
std::copy( c, c + 3, std::ostream_iterator<int>(cout, " ") );
}
[endsect]
[section:gcd_header Header <boost/math/common_factor.hpp>]
[section:gcd_header Header <boost/integer/common_factor.hpp>]
This header simply includes the headers
[@../../../../boost/math/common_factor_ct.hpp <boost/math/common_factor_ct.hpp>]
and [@../../../../boost/math/common_factor_rt.hpp <boost/math/common_factor_rt.hpp>].
[@../../../../boost/integer/common_factor_ct.hpp <boost/integer/common_factor_ct.hpp>]
and [@../../../../boost/integer/common_factor_rt.hpp <boost/integer/common_factor_rt.hpp>].
Note this is a legacy header: it used to contain the actual implementation,
but the compile-time and run-time facilities
@ -243,7 +243,7 @@ were moved to separate headers (since they were independent of each other).
[section:demo Demonstration Program]
The program [@../../../../libs/math/test/common_factor_test.cpp common_factor_test.cpp] is a demonstration of the results from
The program [@../../../../libs/integer/test/common_factor_test.cpp common_factor_test.cpp] is a demonstration of the results from
instantiating various examples of the run-time GCD and LCM function
templates and the compile-time GCD and LCM class templates.
(The run-time GCD and LCM class templates are tested indirectly through
@ -256,7 +256,7 @@ the run-time function templates.)
The greatest common divisor and least common multiple functions are
greatly used in some numeric contexts, including some of the other
Boost libraries. Centralizing these functions to one header improves
code factoring and eases maintainence.
code factoring and eases maintenance.
[endsect]
@ -288,5 +288,3 @@ Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]

View File

@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Removed from library: Standard Integer Types</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="history.html" title="History">

View File

@ -0,0 +1,109 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Extended Euclidean Algorithm</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="gcd_lcm.html" title="Greatest Common Divisor and Least Common Multiple">
<link rel="next" href="mod_inverse.html" title="Modular Multiplicative Inverse">
</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="gcd_lcm.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="mod_inverse.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.extended_euclidean"></a><a class="link" href="extended_euclidean.html" title="Extended Euclidean Algorithm">Extended Euclidean Algorithm</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="extended_euclidean.html#boost_integer.extended_euclidean.introduction">Introduction</a></span></dt>
<dt><span class="section"><a href="extended_euclidean.html#boost_integer.extended_euclidean.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="extended_euclidean.html#boost_integer.extended_euclidean.usage">Usage</a></span></dt>
<dt><span class="section"><a href="extended_euclidean.html#boost_integer.extended_euclidean.references">References</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.extended_euclidean.introduction"></a><a class="link" href="extended_euclidean.html#boost_integer.extended_euclidean.introduction" title="Introduction">Introduction</a>
</h3></div></div></div>
<p>
The extended Euclidean algorithm solves the integer relation <span class="emphasis"><em>mx
+ ny</em></span> = gcd(<span class="emphasis"><em>m</em></span>, <span class="emphasis"><em>n</em></span>) for
<span class="emphasis"><em>x</em></span> and <span class="emphasis"><em>y</em></span>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.extended_euclidean.synopsis"></a><a class="link" href="extended_euclidean.html#boost_integer.extended_euclidean.synopsis" title="Synopsis">Synopsis</a>
</h3></div></div></div>
<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">integer</span><span class="special">/</span><span class="identifier">extended_euclidean</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">integer</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Z</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">euclidean_result_t</span> <span class="special">{</span>
<span class="identifier">Z</span> <span class="identifier">gcd</span><span class="special">;</span>
<span class="identifier">Z</span> <span class="identifier">x</span><span class="special">;</span>
<span class="identifier">Z</span> <span class="identifier">y</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Z</span><span class="special">&gt;</span>
<span class="identifier">euclidean_result_t</span><span class="special">&lt;</span><span class="identifier">Z</span><span class="special">&gt;</span> <span class="identifier">extended_euclidean</span><span class="special">(</span><span class="identifier">Z</span> <span class="identifier">m</span><span class="special">,</span> <span class="identifier">Z</span> <span class="identifier">n</span><span class="special">);</span>
<span class="special">}}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.extended_euclidean.usage"></a><a class="link" href="extended_euclidean.html#boost_integer.extended_euclidean.usage" title="Usage">Usage</a>
</h3></div></div></div>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">m</span> <span class="special">=</span> <span class="number">12</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">n</span> <span class="special">=</span> <span class="number">15</span><span class="special">;</span>
<span class="keyword">auto</span> <span class="identifier">res</span> <span class="special">=</span> <span class="identifier">extended_euclidean</span><span class="special">(</span><span class="identifier">m</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">gcd</span> <span class="special">=</span> <span class="identifier">res</span><span class="special">.</span><span class="identifier">gcd</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">res</span><span class="special">.</span><span class="identifier">x</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">res</span><span class="special">.</span><span class="identifier">y</span><span class="special">;</span>
<span class="comment">// mx + ny = gcd(m,n) should now hold</span>
</pre>
<p>
Unlike most of the library, the extended Euclidean algorithm requires C++11
features.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.extended_euclidean.references"></a><a class="link" href="extended_euclidean.html#boost_integer.extended_euclidean.references" title="References">References</a>
</h3></div></div></div>
<p>
Wagstaff, Samuel S., <span class="emphasis"><em>The Joy of Factoring</em></span>, Vol. 68.
American Mathematical Soc., 2013.
</p>
</div>
</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; 2001-2009 Beman
Dawes, Daryle Walker, Gennaro Prota, John Maddock<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="gcd_lcm.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="mod_inverse.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -3,11 +3,11 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Greatest Common Divisor and Least Common Multiple</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="integer.html" title="Integer Type Selection">
<link rel="next" href="mask.html" title="Integer Masks">
<link rel="next" href="extended_euclidean.html" title="Extended Euclidean Algorithm">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
@ -20,14 +20,14 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="extended_euclidean.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.gcd_lcm"></a><a class="link" href="gcd_lcm.html" title="Greatest Common Divisor and Least Common Multiple">Greatest Common Divisor and Least
Common Multiple</a>
</h2></div></div></div>
<div class="toc"><dl>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.introduction">Introduction</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_function_object">GCD Function
@ -38,7 +38,7 @@
Determination</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.compile_time">Compile time GCD
and LCM determination</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_header">Header &lt;boost/math/common_factor.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_header">Header &lt;boost/integer/common_factor.hpp&gt;</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.demo">Demonstration Program</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.rationale">Rationale</a></span></dt>
<dt><span class="section"><a href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_history">History</a></span></dt>
@ -61,7 +61,7 @@
</h3></div></div></div>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
<span class="special">{</span>
<span class="keyword">namespace</span> <span class="identifier">math</span>
<span class="keyword">namespace</span> <span class="identifier">integer</span>
<span class="special">{</span>
<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">&gt;</span>
@ -102,10 +102,10 @@
Object</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top">&lt;boost/math/common_factor_rt.hpp&gt;</a>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/integer/common_factor_rt.hpp" target="_top">&lt;boost/integer/common_factor_rt.hpp&gt;</a>
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd_evaluator</span>
<span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">gcd_evaluator</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// Types</span>
@ -120,11 +120,11 @@
<span class="special">};</span>
</pre>
<p>
The boost::math::gcd_evaluator class template defines a function object class
to return the greatest common divisor of two integers. The template is parameterized
by a single type, called IntegerType here. This type should be a numeric
type that represents integers. The result of the function object is always
nonnegative, even if either of the operator arguments is negative.
The boost::integer::gcd_evaluator class template defines a function object
class to return the greatest common divisor of two integers. The template
is parameterized by a single type, called IntegerType here. This type should
be a numeric type that represents integers. The result of the function object
is always nonnegative, even if either of the operator arguments is negative.
</p>
<p>
This function object class template is used in the corresponding version
@ -144,10 +144,10 @@
Object</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top">&lt;boost/math/common_factor_rt.hpp&gt;</a>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/integer/common_factor_rt.hpp" target="_top">&lt;boost/integer/common_factor_rt.hpp&gt;</a>
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">lcm_evaluator</span>
<span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">lcm_evaluator</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// Types</span>
@ -162,13 +162,13 @@
<span class="special">};</span>
</pre>
<p>
The boost::math::lcm_evaluator class template defines a function object class
to return the least common multiple of two integers. The template is parameterized
by a single type, called IntegerType here. This type should be a numeric
type that represents integers. The result of the function object is always
nonnegative, even if either of the operator arguments is negative. If the
least common multiple is beyond the range of the integer type, the results
are undefined.
The boost::integer::lcm_evaluator class template defines a function object
class to return the least common multiple of two integers. The template is
parameterized by a single type, called IntegerType here. This type should
be a numeric type that represents integers. The result of the function object
is always nonnegative, even if either of the operator arguments is negative.
If the least common multiple is beyond the range of the integer type, the
results are undefined.
</p>
<p>
This function object class template is used in the corresponding version
@ -188,13 +188,13 @@
Determination</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top">&lt;boost/math/common_factor_rt.hpp&gt;</a>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/integer/common_factor_rt.hpp" target="_top">&lt;boost/integer/common_factor_rt.hpp&gt;</a>
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">&gt;</span>
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">b</span> <span class="special">);</span>
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">gcd</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">b</span> <span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span> <span class="special">&gt;</span>
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">lcm</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">b</span> <span class="special">);</span>
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">lcm</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">b</span> <span class="special">);</span>
<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">IntegerType</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="keyword">constexpr</span> <span class="identifier">IntegerType</span> <span class="identifier">gcd</span><span class="special">(</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">IntegerType</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">Args</span> <span class="keyword">const</span><span class="special">&amp;...</span> <span class="special">);</span>
@ -211,8 +211,8 @@
<span class="identifier">lcm_range</span><span class="special">(</span><span class="identifier">I</span> <span class="identifier">first</span><span class="special">,</span> <span class="identifier">I</span> <span class="identifier">last</span><span class="special">);</span>
</pre>
<p>
The boost::math::gcd function template returns the greatest common (nonnegative)
divisor of the two integers passed to it. <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd_range</span></code>
The boost::integer::gcd function template returns the greatest common (nonnegative)
divisor of the two integers passed to it. <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">gcd_range</span></code>
is the iteration of the above gcd algorithm over a range, returning the greatest
common divisor of all the elements. The algorithm terminates when the gcd
reaches unity or the end of the range. Thus it also returns the iterator
@ -222,7 +222,7 @@
to reach unity.
</p>
<p>
The boost::math::lcm function template returns the least common (nonnegative)
The boost::integer::lcm function template returns the least common (nonnegative)
multiple of the two integers passed to it. As with gcd, there are range and
variadic versions of the function for more than 2 arguments.
</p>
@ -249,17 +249,17 @@
</p></td></tr>
</table></div>
<p>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/math/common_factor_ct.hpp" target="_top">&lt;boost/math/common_factor_ct.hpp&gt;</a>
<span class="bold"><strong>Header: </strong></span> <a href="../../../../../boost/integer/common_factor_ct.hpp" target="_top">&lt;boost/integer/common_factor_ct.hpp&gt;</a>
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">static_gcd_type</span><span class="special">;</span>
<span class="keyword">template</span> <span class="special">&lt;</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value2</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_gcd</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special">&lt;</span><span class="identifier">static_gcd_type</span><span class="special">,</span> <span class="identifier">implementation_defined</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">static_gcd</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special">&lt;</span><span class="identifier">static_gcd_type</span><span class="special">,</span> <span class="identifier">implementation_defined</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="special">};</span>
<span class="keyword">template</span> <span class="special">&lt;</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value1</span><span class="special">,</span> <span class="identifier">static_gcd_type</span> <span class="identifier">Value2</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_lcm</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special">&lt;</span><span class="identifier">static_gcd_type</span><span class="special">,</span> <span class="identifier">implementation_defined</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">static_lcm</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span><span class="special">&lt;</span><span class="identifier">static_gcd_type</span><span class="special">,</span> <span class="identifier">implementation_defined</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="special">};</span>
</pre>
@ -271,8 +271,8 @@
<span class="keyword">long</span></code> for some older compilers.
</p>
<p>
The boost::math::static_gcd and boost::math::static_lcm class templates take
two value-based template parameters of the <span class="emphasis"><em>static_gcd_type</em></span>
The boost::integer::static_gcd and boost::integer::static_lcm class templates
take two value-based template parameters of the <span class="emphasis"><em>static_gcd_type</em></span>
type and inherit from the type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">integral_c</span></code>. Inherited from the base class,
they have a member <span class="emphasis"><em>value</em></span> that is the greatest common
factor or least common multiple, respectively, of the template arguments.
@ -283,7 +283,7 @@
<a name="boost_integer.gcd_lcm.compile_time.h0"></a>
<span class="phrase"><a name="boost_integer.gcd_lcm.compile_time.example"></a></span><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.compile_time.example">Example</a>
</h4>
<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">math</span><span class="special">/</span><span class="identifier">common_factor</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<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">integer</span><span class="special">/</span><span class="identifier">common_factor</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">algorithm</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iterator</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>
@ -294,29 +294,29 @@
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"The GCD and LCM of 6 and 15 are "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">15</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">" and "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">lcm</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">15</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", respectively."</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">gcd</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">15</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">" and "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">lcm</span><span class="special">(</span><span class="number">6</span><span class="special">,</span> <span class="number">15</span><span class="special">)</span> <span class="special">&lt;&lt;</span> <span class="string">", respectively."</span>
<span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"The GCD and LCM of 8 and 9 are "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_gcd</span><span class="special">&lt;</span><span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">&gt;::</span><span class="identifier">value</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">static_gcd</span><span class="special">&lt;</span><span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">&gt;::</span><span class="identifier">value</span>
<span class="special">&lt;&lt;</span> <span class="string">" and "</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">static_lcm</span><span class="special">&lt;</span><span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">&gt;::</span><span class="identifier">value</span>
<span class="special">&lt;&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">static_lcm</span><span class="special">&lt;</span><span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">&gt;::</span><span class="identifier">value</span>
<span class="special">&lt;&lt;</span> <span class="string">", respectively."</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">a</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span> <span class="special">},</span> <span class="identifier">b</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span> <span class="special">},</span> <span class="identifier">c</span><span class="special">[</span><span class="number">3</span><span class="special">];</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">a</span> <span class="special">+</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">gcd_evaluator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;()</span> <span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">a</span> <span class="special">+</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">b</span><span class="special">,</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">integer</span><span class="special">::</span><span class="identifier">gcd_evaluator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;()</span> <span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">c</span> <span class="special">+</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream_iterator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">cout</span><span class="special">,</span> <span class="string">" "</span><span class="special">)</span> <span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.gcd_lcm.gcd_header"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_header" title="Header &lt;boost/math/common_factor.hpp&gt;">Header &lt;boost/math/common_factor.hpp&gt;</a>
<a name="boost_integer.gcd_lcm.gcd_header"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.gcd_header" title="Header &lt;boost/integer/common_factor.hpp&gt;">Header &lt;boost/integer/common_factor.hpp&gt;</a>
</h3></div></div></div>
<p>
This header simply includes the headers <a href="../../../../../boost/math/common_factor_ct.hpp" target="_top">&lt;boost/math/common_factor_ct.hpp&gt;</a>
and <a href="../../../../../boost/math/common_factor_rt.hpp" target="_top">&lt;boost/math/common_factor_rt.hpp&gt;</a>.
This header simply includes the headers <a href="../../../../../boost/integer/common_factor_ct.hpp" target="_top">&lt;boost/integer/common_factor_ct.hpp&gt;</a>
and <a href="../../../../../boost/integer/common_factor_rt.hpp" target="_top">&lt;boost/integer/common_factor_rt.hpp&gt;</a>.
</p>
<p>
Note this is a legacy header: it used to contain the actual implementation,
@ -329,7 +329,7 @@
<a name="boost_integer.gcd_lcm.demo"></a><a class="link" href="gcd_lcm.html#boost_integer.gcd_lcm.demo" title="Demonstration Program">Demonstration Program</a>
</h3></div></div></div>
<p>
The program <a href="../../../../../libs/math/test/common_factor_test.cpp" target="_top">common_factor_test.cpp</a>
The program <a href="../../../../../libs/integer/test/common_factor_test.cpp" target="_top">common_factor_test.cpp</a>
is a demonstration of the results from instantiating various examples of
the run-time GCD and LCM function templates and the compile-time GCD and
LCM class templates. (The run-time GCD and LCM class templates are tested
@ -344,7 +344,7 @@
The greatest common divisor and least common multiple functions are greatly
used in some numeric contexts, including some of the other Boost libraries.
Centralizing these functions to one header improves code factoring and eases
maintainence.
maintenance.
</p>
</div>
<div class="section">
@ -394,7 +394,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="integer.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="extended_euclidean.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>History</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="minmax.html" title="Compile time min/max calculation">

View File

@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Integer Type Selection</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="traits.html" title="Integer Traits">
@ -26,7 +26,7 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.integer"></a><a class="link" href="integer.html" title="Integer Type Selection">Integer Type Selection</a>
</h2></div></div></div>
<div class="toc"><dl>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="integer.html#boost_integer.integer.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="integer.html#boost_integer.integer.easiest">Easiest-to-Manipulate
Types</a></span></dt>
@ -353,10 +353,10 @@
<span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">int_t</span><span class="special">&lt;</span><span class="number">24</span><span class="special">&gt;::</span><span class="identifier">least</span> <span class="identifier">my_var</span><span class="special">;</span> <span class="comment">// my_var has at least 24-bits</span>
<span class="comment">//...</span>
<span class="comment">// This one is guarenteed not to be truncated:</span>
<span class="comment">// This one is guaranteed not to be truncated:</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">int_max_value_t</span><span class="special">&lt;</span><span class="number">1000</span><span class="special">&gt;::</span><span class="identifier">least</span> <span class="identifier">my1000</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>
<span class="comment">//...</span>
<span class="comment">// This one is guarenteed not to be truncated, and as fast</span>
<span class="comment">// This one is guaranteed not to be truncated, and as fast</span>
<span class="comment">// to manipulate as possible, its size may be greater than</span>
<span class="comment">// that of my1000:</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">int_max_value_t</span><span class="special">&lt;</span><span class="number">1000</span><span class="special">&gt;::</span><span class="identifier">fast</span> <span class="identifier">my_fast1000</span> <span class="special">=</span> <span class="number">1000</span><span class="special">;</span>

View File

@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Compile Time log2 Calculation</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="mask.html" title="Integer Masks">
@ -26,7 +26,7 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.log2"></a><a class="link" href="log2.html" title="Compile Time log2 Calculation">Compile Time log2 Calculation</a>
</h2></div></div></div>
<div class="toc"><dl>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="log2.html#boost_integer.log2.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="log2.html#boost_integer.log2.usage">Usage</a></span></dt>
<dt><span class="section"><a href="log2.html#boost_integer.log2.demonstration_program">Demonstration

View File

@ -3,10 +3,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Integer Masks</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="gcd_lcm.html" title="Greatest Common Divisor and Least Common Multiple">
<link rel="prev" href="mod_inverse.html" title="Modular Multiplicative Inverse">
<link rel="next" href="log2.html" title="Compile Time log2 Calculation">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@ -20,13 +20,13 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="gcd_lcm.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="mod_inverse.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.mask"></a><a class="link" href="mask.html" title="Integer Masks">Integer Masks</a>
</h2></div></div></div>
<div class="toc"><dl>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="mask.html#boost_integer.mask.overview">Overview</a></span></dt>
<dt><span class="section"><a href="mask.html#boost_integer.mask.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="mask.html#boost_integer.mask.single_bit_mask_class_template">Single
@ -374,7 +374,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="gcd_lcm.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="mod_inverse.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="log2.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Compile time min/max calculation</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="log2.html" title="Compile Time log2 Calculation">
@ -26,7 +26,7 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.minmax"></a><a class="link" href="minmax.html" title="Compile time min/max calculation">Compile time min/max calculation</a>
</h2></div></div></div>
<div class="toc"><dl>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="minmax.html#boost_integer.minmax.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="minmax.html#boost_integer.minmax.usage">Usage</a></span></dt>
<dt><span class="section"><a href="minmax.html#boost_integer.minmax.example">Example</a></span></dt>

View File

@ -0,0 +1,105 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Modular Multiplicative Inverse</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="extended_euclidean.html" title="Extended Euclidean Algorithm">
<link rel="next" href="mask.html" title="Integer Masks">
</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="extended_euclidean.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.mod_inverse"></a><a class="link" href="mod_inverse.html" title="Modular Multiplicative Inverse">Modular Multiplicative Inverse</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="mod_inverse.html#boost_integer.mod_inverse.introduction">Introduction</a></span></dt>
<dt><span class="section"><a href="mod_inverse.html#boost_integer.mod_inverse.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="mod_inverse.html#boost_integer.mod_inverse.usage">Usage</a></span></dt>
<dt><span class="section"><a href="mod_inverse.html#boost_integer.mod_inverse.references">References</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.mod_inverse.introduction"></a><a class="link" href="mod_inverse.html#boost_integer.mod_inverse.introduction" title="Introduction">Introduction</a>
</h3></div></div></div>
<p>
The modular multiplicative inverse of a number <span class="emphasis"><em>a</em></span> is
that number <span class="emphasis"><em>x</em></span> which satisfies <span class="emphasis"><em>ax</em></span>
= 1 mod <span class="emphasis"><em>p</em></span>. A fast algorithm for computing modular multiplicative
inverses based on the extended Euclidean algorithm exists and is provided
by Boost.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.mod_inverse.synopsis"></a><a class="link" href="mod_inverse.html#boost_integer.mod_inverse.synopsis" title="Synopsis">Synopsis</a>
</h3></div></div></div>
<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">integer</span><span class="special">/</span><span class="identifier">mod_inverse</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">integer</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Z</span><span class="special">&gt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">Z</span><span class="special">&gt;</span> <span class="identifier">mod_inverse</span><span class="special">(</span><span class="identifier">Z</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">Z</span> <span class="identifier">m</span><span class="special">);</span>
<span class="special">}}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.mod_inverse.usage"></a><a class="link" href="mod_inverse.html#boost_integer.mod_inverse.usage" title="Usage">Usage</a>
</h3></div></div></div>
<p>
Multiplicative modular inverses exist if and only if <span class="emphasis"><em>a</em></span>
and <span class="emphasis"><em>m</em></span> are coprime. So for example
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">mod_inverse</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">5</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">should_be_three</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span>
<span class="special">}</span>
<span class="keyword">auto</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">mod_inverse</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="number">4</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">y</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">"There is no inverse of 2 mod 4\n"</span><span class="special">;</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_integer.mod_inverse.references"></a><a class="link" href="mod_inverse.html#boost_integer.mod_inverse.references" title="References">References</a>
</h3></div></div></div>
<p>
Wagstaff, Samuel S., <span class="emphasis"><em>The Joy of Factoring</em></span>, Vol. 68.
American Mathematical Soc., 2013.
</p>
</div>
</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; 2001-2009 Beman
Dawes, Daryle Walker, Gennaro Prota, John Maddock<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="extended_euclidean.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="mask.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Integer Traits</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="Boost.Integer">
<link rel="up" href="../index.html" title="Boost.Integer">
<link rel="prev" href="../index.html" title="Boost.Integer">
@ -26,7 +26,7 @@
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_integer.traits"></a><a class="link" href="traits.html" title="Integer Traits">Integer Traits</a>
</h2></div></div></div>
<div class="toc"><dl>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="traits.html#boost_integer.traits.motivation">Motivation</a></span></dt>
<dt><span class="section"><a href="traits.html#boost_integer.traits.synopsis">Synopsis</a></span></dt>
<dt><span class="section"><a href="traits.html#boost_integer.traits.description">Description</a></span></dt>

View File

@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Boost.Integer</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="index.html" title="Boost.Integer">
<link rel="next" href="boost_integer/traits.html" title="Integer Traits">
</head>
@ -50,12 +50,14 @@
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dl class="toc">
<dt><span class="section"><a href="index.html#boost_integer.overview">Overview</a></span></dt>
<dt><span class="section"><a href="boost_integer/traits.html">Integer Traits</a></span></dt>
<dt><span class="section"><a href="boost_integer/integer.html">Integer Type Selection</a></span></dt>
<dt><span class="section"><a href="boost_integer/gcd_lcm.html">Greatest Common Divisor and Least
Common Multiple</a></span></dt>
<dt><span class="section"><a href="boost_integer/extended_euclidean.html">Extended Euclidean Algorithm</a></span></dt>
<dt><span class="section"><a href="boost_integer/mod_inverse.html">Modular Multiplicative Inverse</a></span></dt>
<dt><span class="section"><a href="boost_integer/mask.html">Integer Masks</a></span></dt>
<dt><span class="section"><a href="boost_integer/log2.html">Compile Time log2 Calculation</a></span></dt>
<dt><span class="section"><a href="boost_integer/minmax.html">Compile time min/max calculation</a></span></dt>
@ -237,12 +239,50 @@
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="boost_integer/extended_euclidean.html" title="Extended Euclidean Algorithm">Extended Euclidean
algorithm</a>.
</p>
</td>
<td>
<p>
<code class="literal"><a href="../../../../boost/integer/extended_euclidean.hpp" target="_top">&lt;boost/integer/extended_euclidean.hpp&gt;</a></code>
</p>
</td>
<td>
<p>
Solves <span class="emphasis"><em>mx + ny = gcd(x,y)</em></span> for <span class="emphasis"><em>x</em></span>
and <span class="emphasis"><em>y</em></span>.
</p>
</td>
</tr>
<tr>
<td>
<p>
<a class="link" href="boost_integer/mod_inverse.html" title="Modular Multiplicative Inverse">Modular multiplicative
inverse</a>.
</p>
</td>
<td>
<p>
<code class="literal"><a href="../../../../boost/integer/mod_inverse.hpp" target="_top">&lt;boost/integer/mod_inverse.hpp&gt;</a></code>
</p>
</td>
<td>
<p>
Given <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>m</em></span>, solves
<span class="emphasis"><em>ax</em></span> = 1 mod <span class="emphasis"><em>m</em></span> for <span class="emphasis"><em>x</em></span>.
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: April 24, 2017 at 17:49:59 GMT</small></p></td>
<td align="left"><p><small>Last revised: November 02, 2018 at 19:38:28 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@ -2,7 +2,6 @@
[quickbook 1.6]
[compatibility-mode 1.5]
[copyright 2001-2009 Beman Dawes, Daryle Walker, Gennaro Prota, John Maddock]
[purpose Integer Type Selection]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@ -65,6 +64,18 @@ compile-time value; and computing min and max of constant expressions.
[Templates for finding the extrema of two numbers:
Use to find a bound based on a minimum or maximum value. Useful for generic programming. ]
]
[
[[link boost_integer.extended_euclidean Extended Euclidean algorithm].]
[[^[@../../../../boost/integer/extended_euclidean.hpp <boost/integer/extended_euclidean.hpp>]]]
[Solves /mx + ny = gcd(x,y)/ for /x/ and /y/.]
]
[
[[link boost_integer.mod_inverse Modular multiplicative inverse].]
[[^[@../../../../boost/integer/mod_inverse.hpp <boost/integer/mod_inverse.hpp>]]]
[Given /a/ and /m/, solves /ax/ = 1 mod /m/ for /x/.]
]
]
[endsect]
@ -317,10 +328,10 @@ The following table describes each template's criteria.
{
boost::int_t<24>::least my_var; // my_var has at least 24-bits
//...
// This one is guarenteed not to be truncated:
// This one is guaranteed not to be truncated:
boost::int_max_value_t<1000>::least my1000 = 1000;
//...
// This one is guarenteed not to be truncated, and as fast
// This one is guaranteed not to be truncated, and as fast
// to manipulate as possible, its size may be greater than
// that of my1000:
boost::int_max_value_t<1000>::fast my_fast1000 = 1000;
@ -364,7 +375,8 @@ for sharing their designs for similar templates.
[endsect]
[include gcd/math-gcd.qbk]
[include modular_arithmetic/extended_euclidean.qbk]
[include modular_arithmetic/mod_inverse.qbk]
[section:mask Integer Masks]

View File

@ -0,0 +1,55 @@
[section:extended_euclidean Extended Euclidean Algorithm]
[section Introduction]
The extended Euclidean algorithm solves the integer relation /mx + ny/ = gcd(/m/, /n/) for /x/ and /y/.
[endsect]
[section Synopsis]
#include <boost/integer/extended_euclidean.hpp>
namespace boost { namespace integer {
template<class Z>
struct euclidean_result_t {
Z gcd;
Z x;
Z y;
};
template<class Z>
euclidean_result_t<Z> extended_euclidean(Z m, Z n);
}}
[endsect]
[section Usage]
int m = 12;
int n = 15;
auto res = extended_euclidean(m, n);
int gcd = res.gcd;
int x = res.x;
int y = res.y;
// mx + ny = gcd(m,n) should now hold
Unlike most of the library, the extended Euclidean algorithm requires C++11 features.
[endsect]
[section References]
Wagstaff, Samuel S., ['The Joy of Factoring], Vol. 68. American Mathematical Soc., 2013.
[endsect]
[endsect]
[/
Copyright 2018 Nick Thompson.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]

View File

@ -0,0 +1,51 @@
[section:mod_inverse Modular Multiplicative Inverse]
[section Introduction]
The modular multiplicative inverse of a number /a/ is that number /x/ which satisfies /ax/ = 1 mod /p/.
A fast algorithm for computing modular multiplicative inverses based on the extended Euclidean algorithm exists and is provided by Boost.
[endsect]
[section Synopsis]
#include <boost/integer/mod_inverse.hpp>
namespace boost { namespace integer {
template<class Z>
boost::optional<Z> mod_inverse(Z a, Z m);
}}
[endsect]
[section Usage]
Multiplicative modular inverses exist if and only if /a/ and /m/ are coprime.
So for example
auto x = mod_inverse(2, 5);
if (x)
{
int should_be_three = x.value();
}
auto y = mod_inverse(2, 4);
if (!y)
{
std::cout << "There is no inverse of 2 mod 4\n";
}
[endsect]
[section References]
Wagstaff, Samuel S., ['The Joy of Factoring], Vol. 68. American Mathematical Soc., 2013.
[endsect]
[endsect]
[/
Copyright 2018 Nick Thompson.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]

View File

@ -0,0 +1,72 @@
/*
* (C) Copyright Nick Thompson 2018.
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_INTEGER_EXTENDED_EUCLIDEAN_HPP
#define BOOST_INTEGER_EXTENDED_EUCLIDEAN_HPP
#include <limits>
#include <stdexcept>
#include <boost/throw_exception.hpp>
namespace boost { namespace integer {
// From "The Joy of Factoring", Algorithm 2.7, with a small optimization to remove tmps from Wikipedia.
// Solves mx + ny = gcd(m,n). Returns tuple with (gcd(m,n), x, y).
template<class Z>
struct euclidean_result_t {
Z gcd;
Z x;
Z y;
};
template<class Z>
euclidean_result_t<typename std::enable_if<std::numeric_limits< Z >::is_signed, Z>::type>
extended_euclidean(Z m, Z n)
{
if (m < 1 || n < 1)
{
BOOST_THROW_EXCEPTION(std::domain_error("Arguments must be strictly positive."));
}
bool swapped = false;
if (m < n)
{
swapped = true;
using std::swap;
swap(m, n);
}
Z u0 = m;
Z u1 = 1;
Z u2 = 0;
Z v0 = n;
Z v1 = 0;
Z v2 = 1;
Z w0;
Z w1;
Z w2;
while(v0 > 0)
{
Z q = u0/v0;
w0 = u0 - q*v0;
w1 = u1 - q*v1;
w2 = u2 - q*v2;
u0 = v0;
u1 = v1;
u2 = v2;
v0 = w0;
v1 = w1;
v2 = w2;
}
if (swapped)
{
return {u0, u2, u1};
}
return {u0, u1, u2};
}
}}
#endif

View File

@ -0,0 +1,54 @@
/*
* (C) Copyright Nick Thompson 2018.
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_INTEGER_MOD_INVERSE_HPP
#define BOOST_INTEGER_MOD_INVERSE_HPP
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/optional.hpp>
#include <boost/integer/extended_euclidean.hpp>
namespace boost { namespace integer {
// From "The Joy of Factoring", Algorithm 2.7.
// Here's some others names I've found for this function:
// PowerMod[a, -1, m] (Mathematica)
// mpz_invert (gmplib)
// modinv (some dude on stackoverflow)
// Would mod_inverse be sometimes mistaken as the modular *additive* inverse?
// In any case, I think this is the best name we can get for this function without agonizing.
template<class Z>
boost::optional<Z> mod_inverse(Z a, Z modulus)
{
if (modulus < 2)
{
BOOST_THROW_EXCEPTION(std::domain_error("Modulus must be > 1."));
}
// make sure a < modulus:
a = a % modulus;
if (a == 0)
{
// a doesn't have a modular multiplicative inverse:
return boost::none;
}
euclidean_result_t<Z> u = extended_euclidean(a, modulus);
if (u.gcd > 1)
{
return boost::none;
}
// x might not be in the range 0 < x < m, let's fix that:
while (u.x <= 0)
{
u.x += modulus;
}
// While indeed this is an inexpensive and comforting check,
// the multiplication overflows and hence makes the check itself buggy.
//BOOST_ASSERT(u.x*a % modulus == 1);
return u.x;
}
}}
#endif

View File

@ -3,6 +3,7 @@
#~ (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import testing ;
import ../../config/checks/config : requires ;
project : requirements <warnings>all <toolset>gcc:<cxxflags>-Wextra ;
@ -16,6 +17,8 @@ test-suite integer
[ run integer_mask_test.cpp ]
[ run static_log2_test.cpp ]
[ run static_min_max_test.cpp ]
[ run extended_euclidean_test.cpp : : : [ requires cxx11_unified_initialization_syntax sfinae_expr ] ]
[ run mod_inverse_test.cpp : : : [ requires cxx11_unified_initialization_syntax sfinae_expr ] ]
[ compile integer_traits_include_test.cpp ]
[ compile integer_include_test.cpp ]
[ compile integer_mask_include_test.cpp ]

View File

@ -0,0 +1,61 @@
/*
* (C) Copyright Nick Thompson 2018.
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (defined(BOOST_MSVC) && (BOOST_MSVC < 1500)) || \
(defined(__clang_major__) && (__clang_major__ == 3) && (__clang_minor__ < 2)) || \
(defined(BOOST_GCC) && defined(BOOST_GCC_CXX11) && BOOST_GCC < 40800)
#define DISABLE_MP_TESTS
#endif
#ifndef DISABLE_MP_TESTS
#include <boost/core/lightweight_test.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/integer/common_factor.hpp>
#include <boost/integer/extended_euclidean.hpp>
using boost::multiprecision::int128_t;
using boost::multiprecision::int256_t;
using boost::integer::extended_euclidean;
using boost::integer::gcd;
template<class Z>
void test_extended_euclidean()
{
// Stress test:
//Z max_arg = std::numeric_limits<Z>::max();
Z max_arg = 500;
for (Z m = max_arg; m > 0; --m)
{
for (Z n = max_arg; n > 0; --n)
{
boost::integer::euclidean_result_t<Z> u = extended_euclidean(m, n);
int256_t gcdmn = gcd(m, n);
int256_t x = u.x;
int256_t y = u.y;
BOOST_TEST_EQ(u.gcd, gcdmn);
BOOST_TEST_EQ(m*x + n*y, gcdmn);
}
}
}
int main()
{
test_extended_euclidean<int16_t>();
test_extended_euclidean<int32_t>();
test_extended_euclidean<int64_t>();
test_extended_euclidean<int128_t>();
return boost::report_errors();;
}
#else
int main()
{
return 0;
}
#endif

73
test/mod_inverse_test.cpp Normal file
View File

@ -0,0 +1,73 @@
/*
* (C) Copyright Nick Thompson 2018.
* Use, modification and distribution are subject to the
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/config.hpp>
#if (defined(BOOST_MSVC) && (BOOST_MSVC < 1500)) || \
(defined(__clang_major__) && (__clang_major__ == 3) && (__clang_minor__ < 2)) || \
(defined(BOOST_GCC) && defined(BOOST_GCC_CXX11) && BOOST_GCC < 40800)
#define DISABLE_MP_TESTS
#endif
#ifndef DISABLE_MP_TESTS
#include <boost/core/lightweight_test.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/integer/common_factor.hpp>
#include <boost/integer/mod_inverse.hpp>
using boost::multiprecision::int128_t;
using boost::multiprecision::int256_t;
using boost::integer::mod_inverse;
using boost::integer::gcd;
template<class Z>
void test_mod_inverse()
{
//Z max_arg = std::numeric_limits<Z>::max();
Z max_arg = 500;
for (Z modulus = 2; modulus < max_arg; ++modulus)
{
if (modulus % 1000 == 0)
{
std::cout << "Testing all inverses modulo " << modulus << std::endl;
}
for (Z a = 1; a < modulus; ++a)
{
Z gcdam = gcd(a, modulus);
boost::optional<Z> inv_a = mod_inverse(a, modulus);
// Should fail if gcd(a, mod) != 1:
if (gcdam > 1)
{
BOOST_TEST(!inv_a);
}
else
{
BOOST_TEST(inv_a.value() > 0);
// Cast to a bigger type so the multiplication won't overflow.
int256_t a_inv = inv_a.value();
int256_t big_a = a;
int256_t m = modulus;
int256_t outta_be_one = (a_inv*big_a) % m;
BOOST_TEST_EQ(outta_be_one, 1);
}
}
}
}
int main()
{
test_mod_inverse<int16_t>();
test_mod_inverse<int32_t>();
test_mod_inverse<int64_t>();
test_mod_inverse<int128_t>();
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif