Multiprecision integers

#include <mp++/integer.hpp>

The integer class

template<std::size_t SSize>
class integer

Multiprecision integer class.

This class represents arbitrary-precision signed integers. It acts as a wrapper around the GMP mpz_t type, with a small value optimisation: integers whose size is up to SSize limbs are stored directly in the storage occupied by the integer object, without resorting to dynamic memory allocation. The value of SSize must be at least 1 and less than an implementation-defined upper limit. On most modern architectures, a limb contains either 32 or 64 bits of data. Thus, for instance, if SSize is set to 2 on a 64-bit system, the small value optimisation will be employed for all integral values less than \(2^{64 \times 2} = 2^{128}\).

When the value of an integer is stored directly within the object, the storage type of the integer is said to be static. When the limb size of the integer exceeds the maximum value SSize, the storage type becomes dynamic. The transition from static to dynamic storage happens transparently whenever the integer value becomes large enough. The demotion from dynamic to static storage usually needs to be requested explicitly. For values of SSize of 1 and 2, optimised implementations of basic arithmetic operations are employed, if supported by the target architecture and if the storage type is static. For larger values of SSize, the mpn_ low-level functions of the GMP API are used if the storage type is static. If the storage type is dynamic, the usual mpz_ functions from the GMP API are used.

This class has the look and feel of a C++ builtin type: it can interact with most of C++’s integral and floating-point primitive types (see the CppInteroperable concept for the full list), and it provides overloaded operators. Differently from the builtin types, however, this class does not allow any implicit conversion to/from other types (apart from bool): construction from and conversion to primitive types must always be requested explicitly. As a side effect, syntax such as

integer<1> n = 5;
int m = n;

will not work, and direct initialization should be used instead:

integer<1> n{5};
int m{n};

Most of the functionality is exposed via plain functions, with the general convention that the functions are named after the corresponding GMP functions minus the leading mpz_ prefix. For instance, the GMP call

mpz_add(rop,a,b);

that writes the result of a + b into rop becomes simply

add(rop,a,b);

where the add() function is resolved via argument-dependent lookup. Function calls with overlapping arguments are allowed, unless noted otherwise.

Multiple overloads of the same functionality are often available. Binary functions in GMP are usually implemented via three-arguments functions, in which the first argument is a reference to the return value. The exponentiation function mpz_pow_ui(), for instance, takes three arguments: the return value, the base and the exponent. There are two overloads of the corresponding exponentiation function for integer:

  • a ternary overload semantically equivalent to mpz_pow_ui(),

  • a binary overload taking as inputs the base and the exponent, and returning the result of the exponentiation.

This allows to avoid having to set up a return value for one-off invocations of pow_ui() (the binary overload will do it for you). For example:

integer<1> r1, r2, n{3};
pow_ui(r1,n,2);   // Ternary pow_ui(): computes n**2 and stores
                  // the result in r1.
r2 = pow_ui(n,2); // Binary pow_ui(): returns n**2, which is then
                  // assigned to r2.

In case of unary functions, there are often three overloads available:

  • a binary overload taking as first parameter a reference to the return value (GMP style),

  • a unary overload returning the result of the operation,

  • a nullary member function that modifies the calling object in-place.

For instance, here are three possible ways of computing the absolute value:

integer<1> r1, r2, n{-5};
abs(r1,n);   // Binary abs(): computes and stores the absolute value
             // of n into r1.
r2 = abs(n); // Unary abs(): returns the absolute value of n, which is
             // then assigned to r2.
n.abs();     // Member function abs(): replaces the value of n with its
             // absolute value.

Note that at this time a subset of the GMP API has been wrapped by integer.

Various overloaded operators are provided. For the common arithmetic operations (+, -, * and /), the type promotion rules are a natural extension of the corresponding rules for native C++ types: if the other argument is a C++ integral, the result will be of type integer, if the other argument is a C++ floating-point the result will be of the same floating-point type. For example:

integer<1> n1{1}, n2{2};
auto res1 = n1 + n2; // res1 is an integer
auto res2 = n1 * 2; // res2 is an integer
auto res3 = 2 - n2; // res3 is an integer
auto res4 = n1 / 2.f; // res4 is a float
auto res5 = 12. / n1; // res5 is a double

The modulo operator % and the bitwise logic operators accept only integer and CppIntegralInteroperable types as arguments, and they always return integer as result. The bit shifting operators << and >> accept only CppIntegralInteroperable types as shift arguments, and they always return integer as result.

The relational operators, ==, !=, <, >, <= and >= will promote the arguments to a common type before comparing them. The promotion rules are the same as in the arithmetic operators (that is, both arguments are promoted to integer if they are both integral types, otherwise they are promoted to the type of the floating-point argument).

Several facilities for interfacing with the GMP library are provided. Specifically, integer features:

  • a constructor and an assignment operator from the GMP integer type mpz_t,

  • a get_mpz_t() method that promotes this to dynamic storage and returns a pointer to the internal mpz_t instance,

  • an mpz_view class, an instance of which can be requested via the get_mpz_view() method, which allows to use integer in the GMP API as a drop-in replacement for const mpz_t function arguments.

The mpz_view class represent a read-only view of an integer object which is implicitly convertible to the type const mpz_t and which is thus usable as an argument to GMP functions. For example:

mpz_t m;
mpz_init_set_si(m,1); // Create an mpz_t with the value 1.
integer<1> n{1}; // Initialize an integer with the value 1.
mpz_add(m,m,n.get_mpz_view()); // Compute the result of n + m and store
                               // it in m using the GMP API.

See the documentation of get_mpz_view() for more details about the mpz_view class. Via the GMP interfacing facilities, it is thus possible to use directly the GMP C API with integer objects whenever necessary (e.g., if a GMP function has not been wrapped yet by mp++).

The integer class supports a simple binary serialisation API, through member functions such as binary_save() and binary_load(), and the corresponding free function overloads. Examples of usage are described in the integer tutorial.

Public Functions

integer()

Default constructor.

The default constructor initialises an integer with static storage type and value 0.

integer(const integer &other)

Copy constructor.

The copy constructor deep-copies other into this, copying the original storage type as well.

Parameters
  • other: the object that will be copied into this.

integer(integer &&other)

Move constructor.

The move constructor will leave other in an unspecified but valid state. The storage type of this will be the same as other’s.

Parameters
  • other: the object that will be moved into this.

integer(const mp_limb_t *p, std::size_t size)

Constructor from an array of limbs.

This constructor will initialise this with the content of the array sized size starting at p. The array is expected to contain the limbs of the desired value for this, ordered from the least significant to the most significant.

For instance, the following code:

::mp_limb_t arr[] = {5,6,7};
integer<1> n{arr, 3};

will initialise n to the value \(5 + 6 \times 2^{N} + 7 \times 2^{2N}\), where \(N\) is the compile-time GMP constant GMP_NUMB_BITS representing the number of value bits in a limb (typically 64 or 32, depending on the platform).

This constructor always initialises this to a non-negative value, and it requires the most significant limb of p to be nonzero. It also requires every member of the input array not to be greater than the GMP_NUMB_MAX GMP constant. If size is zero, this will be initialised to zero without ever dereferencing p.

Parameters
  • p: a pointer to the beginning of the limbs array.

  • size: the size of the limbs array.

Exceptions
  • std::invalid_argument: if the last element of the p array is zero, or if at least one element of the p array is greater than GMP_NUMB_MAX.

  • std::overflow_error: if size is larger than an implementation-defined limit.

integer(integer_bitcnt_t nbits)

Constructor from number of bits.

This constructor will initialise this to zero, allocating enough memory to represent a value with a magnitude of nbits binary digits. The storage type will be static if nbits is small enough, dynamic otherwise. For instance, the code

integer n{integer_bitcnt_t(64)};

will initialise an integer n with value zero and enough storage for a 64-bit value.

Parameters
  • nbits: the number of bits of storage that will be allocated.

Exceptions
  • std::overflow_error: if the value of nbits is larger than an implementation-defined limit.

template<CppInteroperable T>
integer(const T &x)

Generic constructor.

This constructor will initialize an integer with the value of x. The initialization is always successful if x is an integral value (construction from bool yields 1 for true, 0 for false). If x is a floating-point value, the construction will fail if x is not finite. Construction from a floating-point type yields the truncated counterpart of the input value.

Parameters
  • x: value that will be used to initialize this.

Exceptions
  • std::domain_error: if x is a non-finite floating-point value.

template<StringType T>
integer(const T &s, int base = 10)

Constructor from string.

This constructor will initialize this from the StringType s, which must represent an integer value in base base. The expected format is the same as specified by the mpz_set_str() GMP function. base may vary from 2 to 62, or be zero. In the latter case, the base is inferred from the leading characters of the string.

Parameters
  • s: the input string.

  • base: the base used in the string representation.

Exceptions
  • std::invalid_argument: if the base parameter is invalid or if s is not a valid string representation of an integer in the specified base.

  • unspecified: any exception thrown by memory errors in standard containers.

integer(const char *begin, const char *end, int base = 10)

Constructor from range of characters.

This constructor will initialise this from the content of the input half-open range, which is interpreted as the string representation of an integer in base base.

Internally, the constructor will copy the content of the range to a local buffer, add a string terminator, and invoke the constructor from string.

Parameters
  • begin: the begin of the input range.

  • end: the end of the input range.

  • base: the base used in the string representation.

Exceptions
  • unspecified: any exception thrown by the constructor from string, or by memory allocation errors in standard containers.

integer(const mpz_t n)

Copy constructor from mpz_t.

This constructor will initialize this with the value of the GMP integer n. The storage type of this will be static if n fits in the static storage, otherwise it will be dynamic.

Warning

It is the user’s responsibility to ensure that n has been correctly initialized. Calling this constructor with an uninitialized n results in undefined behaviour.

Parameters
  • n: the input GMP integer.

integer(mpz_t &&n)

Move constructor from mpz_t.

This constructor will initialize this with the value of the GMP integer n, transferring the state of n into this. The storage type of this will be static if n fits in the static storage, otherwise it will be dynamic.

Warning

It is the user’s responsibility to ensure that n has been correctly initialized. Calling this constructor with an uninitialized n results in undefined behaviour.

Additionally, the user must ensure that, after construction, mpz_clear() is never called on n: the resources previously owned by n are now owned by this, which will take care of releasing them when the destructor is called.

Note

Due to a compiler bug, this constructor is not available on Microsoft Visual Studio.

Parameters
  • n: the input GMP integer.

integer &operator=(const integer &other)

Copy assignment operator.

This operator will perform a deep copy of other, copying its storage type as well.

Return

a reference to this.

Parameters
  • other: the assignment argument.

integer &operator=(integer &&other)

Move assignment operator.

After the move, other will be in an unspecified but valid state, and the storage type of this will be other’s original storage type.

Return

a reference to this.

Parameters
  • other: the assignment argument.

template<CppInteroperable T>
integer &operator=(const T &x)

Generic assignment operator.

This operator will assign x to this. The storage type of this after the assignment will depend only on the value of x (that is, the storage type will be static if the value of x is small enough, dynamic otherwise). Assignment from floating-point types will assign the truncated counterpart of x.

Return

a reference to this.

Parameters
  • x: the assignment argument.

Exceptions
  • std::domain_error: if x is a non-finite floating-point value.

template<StringType T>
integer &operator=(const T &s)

Assignment from string.

The body of this operator is equivalent to:

return *this = integer{s};

That is, a temporary integer is constructed from the StringType s and it is then move-assigned to this.

Return

a reference to this.

Parameters
  • s: the string that will be used for the assignment.

Exceptions
  • unspecified: any exception thrown by the constructor from string.

integer &operator=(const mpz_t n)

Copy assignment from mpz_t.

This assignment operator will copy into this the value of the GMP integer n. The storage type of this after the assignment will be static if n fits in the static storage, otherwise it will be dynamic.

Warning

It is the user’s responsibility to ensure that n has been correctly initialized. Calling this operator with an uninitialized n results in undefined behaviour. Also, no aliasing is allowed: the data in n must be completely distinct from the data in this (e.g., if n is an mpz_view of this then it might point to internal data of this, and the behaviour of this operator will thus be undefined).

Return

a reference to this.

Parameters
  • n: the input GMP integer.

integer &operator=(mpz_t &&n)

Move assignment from mpz_t.

This assignment operator will move into this the GMP integer n. The storage type of this after the assignment will be static if n fits in the static storage, otherwise it will be dynamic.

Warning

It is the user’s responsibility to ensure that n has been correctly initialized. Calling this operator with an uninitialized n results in undefined behaviour. Also, no aliasing is allowed: the data in n must be completely distinct from the data in this (e.g., if n is an mpz_view of this then it might point to internal data of this, and the behaviour of this operator will thus be undefined).

Additionally, the user must ensure that, after the assignment, mpz_clear() is never called on n: the resources previously owned by n are now owned by this, which will take care of releasing them when the destructor is called.

Note

Due to a compiler bug, this operator is not available on Microsoft Visual Studio.

Return

a reference to this.

Parameters
  • n: the input GMP integer.

integer &set_zero()

Set to zero.

After calling this method, the storage type of this will be static and its value will be zero.

Note

This is a specialised higher-performance alternative to the assignment operator.

Return

a reference to this.

integer &set_one()

Set to one.

After calling this method, the storage type of this will be static and its value will be one.

Note

This is a specialised higher-performance alternative to the assignment operator.

Return

a reference to this.

integer &set_negative_one()

Set to minus one.

After calling this method, the storage type of this will be static and its value will be minus one.

Note

This is a specialised higher-performance alternative to the assignment operator.

Return

a reference to this.

bool is_static() const

Test for static storage.

Return

true if the storage type is static, false otherwise.

bool is_dynamic() const

Check for dynamic storage.

Return

true if the storage type is dynamic, false otherwise.

std::string to_string(int base = 10) const

Conversion to string.

This method will convert this into a string in base base using the GMP function mpz_get_str().

Return

a string representation of this.

Parameters
  • base: the desired base.

Exceptions
  • std::invalid_argument: if base is smaller than 2 or greater than 62.

template<CppInteroperable T>
operator T() const

Generic conversion operator.

This operator will convert this to a CppInteroperable type. Conversion to bool yields false if this is zero, true otherwise. Conversion to other integral types yields the exact result, if representable by the target CppInteroperable type. Conversion to floating-point types might yield inexact values and infinities.

Return

this converted to the target type.

Exceptions
  • std::overflow_error: if the target type is an integral type and the value of this cannot be represented by it.

template<CppInteroperable T>
bool get(T &rop) const

Generic conversion method.

This method, similarly to the conversion operator, will convert this to a CppInteroperable type, storing the result of the conversion into rop. Differently from the conversion operator, this method does not raise any exception: if the conversion is successful, the method will return true, otherwise the method will return false. If the conversion fails, rop will not be altered.

Return

true if the conversion succeeded, false otherwise. The conversion can fail only if rop is a C++ integral which cannot represent the value of this.

Parameters
  • rop: the variable which will store the result of the conversion.

bool promote()

Promote to dynamic storage.

This method will promote the storage type of this from static to dynamic.

Return

false if the storage type of this is already dynamic and no promotion takes place, true otherwise.

bool demote()

Demote to static storage.

This method will demote the storage type of this from dynamic to static.

Return

false if the storage type of this is already static and no demotion takes place, or if the current value of this does not fit in static storage, true otherwise.

std::size_t nbits() const

Size in bits.

Return

the number of bits needed to represent this. If this is zero, zero will be returned.

Exceptions
  • std::overflow_error: if the size in bits of this is larger than an implementation-defined value.

std::size_t size() const

Size in limbs.

Return

the number of limbs needed to represent this. If this is zero, zero will be returned.

int sgn() const

Sign.

Return

0 if this is zero, 1 if this is positive, -1 if this is negative.

mpz_view get_mpz_view() const

Get an mpz_t view.

This method will return an object of an unspecified type mpz_view which is implicitly convertible to a const pointer to an mpz_t struct (and which can thus be used as a const mpz_t parameter in GMP functions). In addition to the implicit conversion operator, the const mpz_t object can also be retrieved via the get() method of the mpz_view class. The view provides a read-only GMP-compatible representation of the integer stored in this.

Note

It is important to keep in mind the following facts about the returned mpz_view object:

  • mpz_view objects are strictly read-only: it is impossible to alter this through an mpz_view, and mpz_view objects can be used in the GMP API only where a const mpz_t parameter is expected;

  • mpz_view objects can only be move-constructed (the other constructors and the assignment operators are disabled);

  • the returned object and the pointer returned by its get() method might reference internal data belonging to this, and they can thus be used safely only during the lifetime of this;

  • the lifetime of the pointer returned by the get() method is tied to the lifetime of the mpz_view object (that is, if the mpz_view object is destroyed, any pointer previously returned by get() becomes invalid);

  • any modification to this will also invalidate the view and the pointer.

Return

an mpz view of this.

integer &neg()

Negate in-place.

This method will set this to -this.

Return

a reference to this.

integer &abs()

In-place absolute value.

This method will set this to its absolute value.

Return

a reference to this.

integer &nextprime()

Compute next prime number (in-place version).

This method will set this to the first prime number greater than the current value.

Return

a reference to this.

int probab_prime_p(int reps = 25) const

Test primality.

This method will run a series of probabilistic tests to determine if this is a prime number. It will return 2 if this is definitely a prime, 1 if this is probably a prime and 0 if this is definitely not-prime.

Return

an integer indicating if this is a prime.

Parameters
  • reps: the number of tests to run.

Exceptions
  • std::invalid_argument: if reps is less than 1 or if this is negative.

integer &sqrt()

Integer square root (in-place version).

This method will set this to its integer square root.

Return

a reference to this.

Exceptions
  • std::domain_error: if this is negative.

bool odd_p() const

Test if value is odd.

Return

true if this is odd, false otherwise.

bool even_p() const

Test if value is even.

Return

true if this is even, false otherwise.

detail::integer_union<SSize> &_get_union()

Return a reference to the internal union.

This method returns a reference to the union used internally to implement the integer class.

Return

a reference to the internal union member.

const detail::integer_union<SSize> &_get_union() const

Return a const reference to the internal union.

This method returns a const reference to the union used internally to implement the integer class.

Return

a const reference to the internal union member.

std::remove_extent<mpz_t>::type *get_mpz_t()

Get a pointer to the dynamic storage.

This method will first promote this to dynamic storage (if this is not already employing dynamic storage), and it will then return a pointer to the internal mpz_t structure. The returned pointer can be used as an argument for the functions of the GMP API.

Note

The returned pointer is a raw, non-owning pointer tied to the lifetime of this. Calling demote() or assigning an integer with static storage to this will invalidate the returned pointer.

Return

a pointer to the internal mpz_t structure.

bool is_zero() const

Test if the value is zero.

Return

true if the value represented by this is zero, false otherwise.

bool is_one() const

Test if the value is equal to one.

Return

true if the value represented by this is 1, false otherwise.

bool is_negative_one() const

Test if the value is equal to minus one.

Return

true if the value represented by this is -1, false otherwise.

std::size_t binary_size() const

Size of the serialised binary representation.

This method will return a value representing the number of bytes necessary to serialise this into a memory buffer in binary format via one of the available binary_save() overloads. The returned value is platform-dependent.

Return

the number of bytes needed for the binary serialisation of this.

Exceptions
  • std::overflow_error: if the size in limbs of this is larger than an implementation-defined limit.

std::size_t binary_save(char *dest) const

Serialise into a memory buffer.

This method will write into dest a binary representation of this. The serialised representation produced by this method can be read back with one of the binary_load() overloads.

dest must point to a memory area whose size is at least equal to the value returned by binary_size(), otherwise the behaviour will be undefined. dest does not have any special alignment requirements.

Warning

The binary representation produced by this method is compiler, platform and architecture specific, and it is subject to possible breaking changes in future versions of mp++. Thus, it should not be used as an exchange format or for long-term data storage.

Return

the number of bytes written into dest (i.e., the output of binary_size()).

Parameters
  • dest: a pointer to a memory buffer into which the serialised representation of this will be written.

Exceptions

std::size_t binary_save(std::vector<char> &dest) const

Serialise into a std::vector<char>.

This method will write into dest a binary representation of this. The serialised representation produced by this method can be read back with one of the binary_load() overloads.

The size of dest must be at least equal to the value returned by binary_size(). If that is not the case, dest will be resized to binary_size().

Warning

The binary representation produced by this method is compiler, platform and architecture specific, and it is subject to possible breaking changes in future versions of mp++. Thus, it should not be used as an exchange format or for long-term data storage.

Return

the number of bytes written into dest (i.e., the output of binary_size()).

Parameters
  • dest: a vector that will hold the serialised representation of this.

Exceptions
  • std::overflow_error: if the binary size of this is larger than an implementation-defined limit.

  • unspecified: any exception thrown by binary_size(), or by memory errors in standard containers.

template<std::size_t S>
std::size_t binary_save(std::array<char, S> &dest) const

Serialise into a std::array<char>.

This method will write into dest a binary representation of this. The serialised representation produced by this method can be read back with one of the binary_load() overloads.

The size of dest must be at least equal to the value returned by binary_size(). If that is not the case, no data will be written to dest and zero will be returned.

Warning

The binary representation produced by this method is compiler, platform and architecture specific, and it is subject to possible breaking changes in future versions of mp++. Thus, it should not be used as an exchange format or for long-term data storage.

Return

the number of bytes written into dest (i.e., the output of binary_size() if dest provides enough storage to store this, zero otherwise).

Parameters
  • dest: an array that will hold the serialised representation of this.

Exceptions

std::size_t binary_save(std::ostream &dest) const

Serialise into a std::ostream.

This method will write into the output stream dest a binary representation of this, starting from the current stream position. The serialised representation produced by this method can be read back with one of the binary_load() overloads.

If the serialisation is successful (that is, no stream error state is ever detected in dest after write operations), then the binary size of this (that is, the number of bytes written into dest) will be returned. Otherwise, zero will be returned. Note that a return value of zero does not necessarily imply that no bytes were written into dest, just that an error occurred at some point during the serialisation process.

Warning

The binary representation produced by this method is compiler, platform and architecture specific, and it is subject to possible breaking changes in future versions of mp++. Thus, it should not be used as an exchange format or for long-term data storage.

Return

the output of binary_size() if the serialisation was successful, zero otherwise.

Parameters
  • dest: the destination stream.

Exceptions
  • std::overflow_error: in case of internal overflows.

  • unspecified: any exception thrown by binary_size(), or by the public interface of std::ostream.

std::size_t binary_load(const char *src)

Load a value from a memory buffer.

This method will load into this the content of the memory buffer starting at src, which must contain the serialised representation of an integer produced by one of the binary_save() overloads.

dest does not have any special alignment requirements.

Warning

Although this method performs a few consistency checks on the data in src, it cannot ensure complete safety against maliciously crafted data. Users are advised to use this method only with trusted data.

Return

the number of bytes read from src (that is, the output of binary_size() after the deserialisation into this has successfully completed).

Parameters
  • src: the source memory buffer.

Exceptions
  • std::overflow_error: if the computation of the size of the serialised value leads to overflow.

  • std::invalid_argument: if invalid data is detected in src.

std::size_t binary_load(const std::vector<char> &src)

Load a value from a std::vector<char>.

This method will load into this the content of src, which must contain the serialised representation of an integer produced by one of the binary_save() overloads.

The serialised representation of the integer must start at the beginning of src, but it can end before the end of src. Data past the end of the serialised representation of the integer will be ignored.

Warning

Although this method performs a few consistency checks on the data in src, it cannot ensure complete safety against maliciously crafted data. Users are advised to use this method only with trusted data.

Return

the number of bytes read from src (that is, the output of binary_size() after the deserialisation into this has successfully completed).

Parameters
  • src: the source std::vector<char>.

Exceptions
  • std::overflow_error: if the computation of the size of the serialised value leads to overflow.

  • std::invalid_argument: if invalid data is detected in src.

template<std::size_t S>
std::size_t binary_load(const std::array<char, S> &src)

Load a value from a std::array<char>.

This method will load into this the content of src, which must contain the serialised representation of an integer produced by one of the binary_save() overloads.

The serialised representation of the integer must start at the beginning of src, but it can end before the end of src. Data past the end of the serialised representation of the integer will be ignored.

Warning

Although this method performs a few consistency checks on the data in src, it cannot ensure complete safety against maliciously crafted data. Users are advised to use this method only with trusted data.

Return

the number of bytes read from src (that is, the output of binary_size() after the deserialisation into this has successfully completed).

Parameters
  • src: the source std::array<char>.

Exceptions
  • std::overflow_error: if the computation of the size of the serialised value leads to overflow.

  • std::invalid_argument: if invalid data is detected in src.

std::size_t binary_load(std::istream &src)

Load a value from a std::istream.

This method will load into this the content of src, which must contain the serialised representation of an integer produced by one of the binary_save() overloads.

The serialised representation of the integer must start at the current position of src, but src can contain other data before and after the serialised integer value. Data past the end of the serialised representation of the integer will be ignored. If a stream error state is detected at any point of the deserialisation process after a read operation, zero will be returned and this will not have been modified. Note that a return value of zero does not necessarily imply that no bytes were read from src, just that an error occurred at some point during the serialisation process.

Warning

Although this method performs a few consistency checks on the data in src, it cannot ensure complete safety against maliciously crafted data. Users are advised to use this method only with trusted data.

Return

the number of bytes read from src (that is, the output of binary_size() after the deserialisation into this has successfully completed), or zero if a stream error occurs.

Parameters
  • src: the source std::istream.

Exceptions
  • std::overflow_error: in case of internal overflows.

  • std::invalid_argument: if invalid data is detected in src.

  • unspecified: any exception thrown by memory errors in standard containers, the public interface of std::istream, or binary_size().

Public Static Attributes

constexpr std::size_t ssize = SSize

Alias for the template parameter SSize.

Types

type mp_limb_t

This type is defined by the GMP library. It is used to represents a limb, that is, the part of a multiprecision integer that fits in a single machine word. This is an unsigned integral type, typically 64 or 32 bits wide.

type mp_bitcnt_t

This type is defined by the GMP library. It is an unsigned integral type used to count bits in a multiprecision number.

enum class mppp::integer_bitcnt_t : mp_bitcnt_t

A strongly-typed counterpart to mp_bitcnt_t, used in the constructor of integer from number of bits.

Concepts

template<typename T, typename U>
concept mppp::IntegerOpTypes

This concept is satisfied if the types T and U are suitable for use in the generic binary operators and functions involving integer. Specifically, the concept will be true if either:

  • T and U are both integer with the same static size SSize, or

  • one type is an integer and the other is a CppInteroperable type.

Note that the modulo, bit-shifting and bitwise logic operators have additional restrictions.

A corresponding boolean type trait called are_integer_op_types is also available (even if the compiler does not support concepts).

template<typename T, typename U>
concept mppp::IntegerIntegralOpTypes

This concept is satisfied if the types T and U are suitable for use in the generic binary operators and functions involving integer and C++ integral types. Specifically, the concept will be true if either:

  • T and U are both integer with the same static size, or

  • one type is an integer and the other is a CppIntegralInteroperable type.

A corresponding boolean type trait called are_integer_integral_op_types is also available (even if the compiler does not support concepts).

template<typename T, std::size_t SSize>
concept mppp::IntegerBinarySaveDest

This concept is satisfied if T is a type into which the serialised binary representation of an integer with static size SSize can be written. In other words, the concept is satisfied if an object of type T can be passed as an argument to one of the mppp::integer::binary_save() overloads.

template<typename T, std::size_t SSize>
concept mppp::IntegerBinaryLoadSrc

This concept is satisfied if T is a type from which the serialised binary representation of an integer with static size SSize can be loaded. In other words, the concept is satisfied if an object of type T can be passed as an argument to one of the mppp::integer::binary_load() overloads.

Functions

Much of the functionality of the integer class is exposed via plain functions. These functions mimic the GMP API where appropriate, but a variety of convenience/generic overloads is provided as well.

Assignment

template<std::size_t SSize>
mppp::integer<SSize> &mppp::set_zero(mppp::integer<SSize> &n)

Set to zero.

After calling this function, the storage type of n will be static and its value will be zero.

Note

This is a specialised higher-performance alternative to the assignment operator.

Parameters

n – the argument.

Returns

a reference to n.

template<std::size_t SSize>
mppp::integer<SSize> &mppp::set_one(mppp::integer<SSize> &n)

Set to one.

After calling this function, the storage type of n will be static and its value will be one.

Note

This is a specialised higher-performance alternative to the assignment operator.

Parameters

n – the argument.

Returns

a reference to n.

template<std::size_t SSize>
mppp::integer<SSize> &mppp::set_negative_one(mppp::integer<SSize> &n)

Set to minus one.

After calling this function, the storage type of n will be static and its value will be minus one.

Note

This is a specialised higher-performance alternative to the assignment operator.

Parameters

n – the argument.

Returns

a reference to n.

template<std::size_t SSize>
void mppp::swap(mppp::integer<SSize> &n1, mppp::integer<SSize> &n2) noexcept

New in version 0.15.

Swap.

This function will efficiently swap the values of n1 and n2.

Parameters
  • n1 – the first argument.

  • n2 – the second argument.

Conversion

template<CppInteroperable T, std::size_t SSize>
bool mppp::get(T &rop, const integer<SSize> &n)

Generic conversion function for integer.

This function will convert the input integer n to a CppInteroperable type, storing the result of the conversion into rop. If the conversion is successful, the function will return true, otherwise the function will return false. If the conversion fails, rop will not be altered.

Return

true if the conversion succeeded, false otherwise. The conversion can fail only if rop is a C++ integral which cannot represent the value of n.

Parameters
  • rop: the variable which will store the result of the conversion.

  • n: the input integer.

Arithmetic

template<std::size_t SSize>
integer<SSize> &mppp::add(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Ternary integer addition.

This function will set rop to op1 + op2.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize, CppUnsignedIntegralInteroperable T>
integer<SSize> &mppp::add_ui(integer<SSize> &rop, const integer<SSize> &op1, const T &op2)

Ternary integer addition with C++ unsigned integral types.

This function, which sets rop to op1 + op2, can be a faster alternative to the integer addition function if op2 fits in a single limb.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize, CppSignedIntegralInteroperable T>
integer<SSize> &mppp::add_si(integer<SSize> &rop, const integer<SSize> &op1, const T &op2)

Ternary integer addition with C++ signed integral types.

This function, which sets rop to op1 + op2, can be a faster alternative to the integer addition function if op2 fits in a single limb.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize>
integer<SSize> &mppp::sub(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Ternary integer subtraction.

This function will set rop to op1 - op2.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize, CppUnsignedIntegralInteroperable T>
integer<SSize> &mppp::sub_ui(integer<SSize> &rop, const integer<SSize> &op1, const T &op2)

Ternary integer subtraction with C++ unsigned integral types.

This function, which sets rop to op1 - op2, can be a faster alternative to the integer subtraction function if op2 fits in a single limb.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize, CppSignedIntegralInteroperable T>
integer<SSize> &mppp::sub_si(integer<SSize> &rop, const integer<SSize> &op1, const T &op2)

Ternary integer subtraction with C++ signed integral types.

This function, which sets rop to op1 - op2, can be a faster alternative to the integer subtraction function if op2 fits in a single limb.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize>
integer<SSize> &mppp::mul(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Ternary multiplication.

This function will set rop to op1 * op2.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize>
integer<SSize> &mppp::addmul(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Ternary multiply–add.

This function will set rop to rop + op1 * op2.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize>
integer<SSize> &mppp::submul(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Ternary multiply–sub.

This function will set rop to rop - op1 * op2.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first argument.

  • op2: the second argument.

template<std::size_t SSize>
integer<SSize> &mppp::mul_2exp(integer<SSize> &rop, const integer<SSize> &n, mp_bitcnt_t s)

Ternary left shift.

This function will set rop to n multiplied by 2**s.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the multiplicand.

  • s: the bit shift value.

Exceptions
  • std::overflow_error: if s is larger than an implementation-defined limit.

template<std::size_t SSize>
integer<SSize> &mppp::neg(integer<SSize> &rop, const integer<SSize> &n)

Binary negation.

This method will set rop to -n.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the integer that will be negated.

template<std::size_t SSize>
integer<SSize> mppp::neg(const integer<SSize> &n)

Unary negation.

Return

-n.

Parameters
  • n: the integer that will be negated.

template<std::size_t SSize>
integer<SSize> &mppp::abs(integer<SSize> &rop, const integer<SSize> &n)

Binary absolute value.

This function will set rop to the absolute value of n.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the argument.

template<std::size_t SSize>
integer<SSize> mppp::abs(const integer<SSize> &n)

Unary absolute value.

Return

the absolute value of n.

Parameters
  • n: the argument.

Division

template<std::size_t SSize>
void mppp::tdiv_qr(integer<SSize> &q, integer<SSize> &r, const integer<SSize> &n, const integer<SSize> &d)

Ternary truncated division with remainder.

This function will set q to the truncated quotient n / d and r to n % d. The remainder r has the same sign as n. q and r must be two distinct objects.

Parameters
  • q: the quotient.

  • r: the remainder.

  • n: the dividend.

  • d: the divisor.

Exceptions
  • std::invalid_argument: if q and r are the same object.

  • zero_division_error: if d is zero.

template<std::size_t SSize>
integer<SSize> &mppp::tdiv_q(integer<SSize> &q, const integer<SSize> &n, const integer<SSize> &d)

Ternary truncated division without remainder.

This function will set q to the truncated quotient n / d.

Return

a reference to q.

Parameters
  • q: the quotient.

  • n: the dividend.

  • d: the divisor.

Exceptions
  • zero_division_error: if d is zero.

template<std::size_t SSize>
integer<SSize> &mppp::divexact(integer<SSize> &rop, const integer<SSize> &n, const integer<SSize> &d)

Exact division (ternary version).

This function will set rop to the quotient of n and d.

Warning

If d does not divide n exactly, the behaviour will be undefined.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the dividend.

  • d: the divisor.

template<std::size_t SSize>
integer<SSize> mppp::divexact(const integer<SSize> &n, const integer<SSize> &d)

Exact division (binary version).

Warning

If d does not divide n exactly, the behaviour will be undefined.

Return

the quotient of n and d.

Parameters
  • n: the dividend.

  • d: the divisor.

template<std::size_t SSize>
integer<SSize> &mppp::divexact_gcd(integer<SSize> &rop, const integer<SSize> &n, const integer<SSize> &d)

Exact division with positive divisor (ternary version).

This function will set rop to the quotient of n and d.

Warning

If d does not divide n exactly, or if d is not strictly positive, the behaviour will be undefined.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the dividend.

  • d: the divisor.

template<std::size_t SSize>
integer<SSize> mppp::divexact_gcd(const integer<SSize> &n, const integer<SSize> &d)

Exact division with positive divisor (binary version).

Warning

If d does not divide n exactly, or if d is not strictly positive, the behaviour will be undefined.

Return

the quotient of n and d.

Parameters
  • n: the dividend.

  • d: the divisor.

template<std::size_t SSize>
integer<SSize> &mppp::tdiv_q_2exp(integer<SSize> &rop, const integer<SSize> &n, mp_bitcnt_t s)

Ternary right shift.

This function will set rop to n divided by 2**s. rop will be the truncated result of the division.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the dividend.

  • s: the bit shift value.

Comparison

template<std::size_t SSize>
int mppp::cmp(const integer<SSize> &op1, const integer<SSize> &op2)

Comparison function for integer.

Return

0 if op1 == op2, a negative value if op1 < op2, a positive value if op1 > op2.

Parameters
  • op1: first argument.

  • op2: second argument.

template<std::size_t SSize>
int mppp::sgn(const integer<SSize> &n)

Sign function.

Return

0 if n is zero, 1 if n is positive, -1 if n is negative.

Parameters
  • n: the integer whose sign will be computed.

template<std::size_t SSize>
bool mppp::odd_p(const integer<SSize> &n)

Test if integer is odd.

Return

true if n is odd, false otherwise.

Parameters
  • n: the argument.

template<std::size_t SSize>
bool mppp::even_p(const integer<SSize> &n)

Test if integer is even.

Return

true if n is even, false otherwise.

Parameters
  • n: the argument.

template<std::size_t SSize>
bool mppp::is_zero(const integer<SSize> &n)

Test if an integer is zero.

Return

true if n is zero, false otherwise.

Parameters
  • n: the integer to be tested.

template<std::size_t SSize>
bool mppp::is_one(const integer<SSize> &n)

Test if an integer is equal to one.

Return

true if n is equal to 1, false otherwise.

Parameters
  • n: the integer to be tested.

template<std::size_t SSize>
bool mppp::is_negative_one(const integer<SSize> &n)

Test if an integer is equal to minus one.

Return

true if n is equal to -1, false otherwise.

Parameters
  • n: the integer to be tested.

Logic and bit fiddling

New in version 0.6.

template<std::size_t SSize>
integer<SSize> &mppp::bitwise_not(integer<SSize> &rop, const integer<SSize> &op)

Bitwise NOT for integer.

This function will set rop to the bitwise NOT (i.e., the one’s complement) of op. Negative operands are treated as-if they were represented using two’s complement.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op: the operand.

template<std::size_t SSize>
integer<SSize> &mppp::bitwise_ior(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Bitwise OR for integer.

This function will set rop to the bitwise OR of op1 and op2. Negative operands are treated as-if they were represented using two’s complement.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first operand.

  • op2: the second operand.

template<std::size_t SSize>
integer<SSize> &mppp::bitwise_and(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Bitwise AND for integer.

This function will set rop to the bitwise AND of op1 and op2. Negative operands are treated as-if they were represented using two’s complement.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first operand.

  • op2: the second operand.

template<std::size_t SSize>
integer<SSize> &mppp::bitwise_xor(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

Bitwise XOR for integer.

This function will set rop to the bitwise XOR of op1 and op2. Negative operands are treated as-if they were represented using two’s complement.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first operand.

  • op2: the second operand.

Number theoretic functions

template<std::size_t SSize>
integer<SSize> &mppp::gcd(integer<SSize> &rop, const integer<SSize> &op1, const integer<SSize> &op2)

GCD (ternary version).

This function will set rop to the GCD of op1 and op2. The result is always nonnegative. If both operands are zero, zero is returned.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • op1: the first operand.

  • op2: the second operand.

template<std::size_t SSize>
integer<SSize> mppp::gcd(const integer<SSize> &op1, const integer<SSize> &op2)

GCD (binary version).

Return

the GCD of op1 and op2.

Parameters
  • op1: the first operand.

  • op2: the second operand.

template<std::size_t SSize>
integer<SSize> &mppp::fac_ui(integer<SSize> &rop, unsigned long n)

Factorial.

This function will set rop to the factorial of n.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the argument for the factorial.

Exceptions
  • std::invalid_argument: if n is larger than an implementation-defined limit.

template<std::size_t SSize>
integer<SSize> &mppp::bin_ui(integer<SSize> &rop, const integer<SSize> &n, unsigned long k)

Binomial coefficient (ternary version).

This function will set rop to the binomial coefficient of n and k. Negative values of n are supported.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the top argument.

  • k: the bottom argument.

template<std::size_t SSize>
integer<SSize> mppp::bin_ui(const integer<SSize> &n, unsigned long k)

Binomial coefficient (binary version).

Return

the binomial coefficient of n and k.

Parameters
  • n: the top argument.

  • k: the bottom argument.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> auto mppp::binomial(const T & n, const U & k)

Generic binomial coefficient.

This function will compute the binomial coefficient \({{n}\choose{k}}\), supporting integral input values. The implementation can handle positive and negative values for both the top and the bottom argument.

The return type is always an integer.

Return

\( {{n}\choose{k}} \).

Parameters
  • n: the top argument.

  • k: the bottom argument.

Exceptions
  • std::overflow_error: if k is outside an implementation-defined range.

template<std::size_t SSize>
integer<SSize> &mppp::nextprime(integer<SSize> &rop, const integer<SSize> &n)

Compute next prime number (binary version).

This function will set rop to the first prime number greater than n. Note that for negative values of n this function always returns 2.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • n: the integer argument.

template<std::size_t SSize>
integer<SSize> mppp::nextprime(const integer<SSize> &n)

Compute next prime number (unary version).

Return

the first prime number greater than n.

Parameters
  • n: the integer argument.

template<std::size_t SSize>
int mppp::probab_prime_p(const integer<SSize> &n, int reps = 25)

Test primality.

This is the free-function version of mppp::integer::probab_prime_p().

Return

an integer indicating if n is a prime.

Parameters
  • n: the integer whose primality will be tested.

  • reps: the number of tests to run.

Exceptions

Exponentiation

template<std::size_t SSize>
integer<SSize> &mppp::pow_ui(integer<SSize> &rop, const integer<SSize> &base, unsigned long exp)

Ternary exponentiation for integer.

This function will set rop to base**exp.

Return

a reference to rop.

Parameters
  • rop: the return value.

  • base: the base.

  • exp: the exponent.

template<std::size_t SSize>
integer<SSize> mppp::pow_ui(const integer<SSize> &base, unsigned long exp)

Binary exponentiation for integer.

Return

base**exp.

Parameters
  • base: the base.

  • exp: the exponent.

template<typename T, typename U>requires IntegerOpTypes<T, U> auto mppp::pow(const T & base, const U & exp)

Generic binary exponentiation for integer.

This function will raise base to the power exp, and return the result. If one of the arguments is a floating-point value, then the result will be computed via std::pow() and it will also be a floating-point value. Otherwise, the result will be an integer. In case of a negative integral exponent and integral base, the result will be zero unless the absolute value of base is 1.

Return

base**exp.

Parameters
  • base: the base.

  • exp: the exponent.

Exceptions
  • std::overflow_error: if base and exp are integrals and exp is non-negative and outside the range of unsigned long.

  • zero_division_error: if base and exp are integrals and base is zero and exp is negative.

Roots

template<std::size_t SSize>
mppp::integer<SSize> &mppp::sqrt(mppp::integer<SSize> &rop, const mppp::integer<SSize> &n)

Binary integer square root.

This function will set rop to the truncated integer part of the square root of n.

Parameters
  • rop – the return value.

  • n – the argument.

Returns

a reference to rop.

Throws

std::domain_error – if n is negative.

template<std::size_t SSize>
mppp::integer<SSize> mppp::sqrt(const mppp::integer<SSize> &n)

Unary integer square root.

This function will return the truncated integer part of the square root of n.

Parameters

n – the argument.

Returns

the integer square root of n.

Throws

std::domain_error – if n is negative.

template<std::size_t SSize>
void mppp::sqrtrem(mppp::integer<SSize> &rop, mppp::integer<SSize> &rem, const mppp::integer<SSize> &n)

New in version 0.12.

integer square root with remainder.

This function will set rop to the truncated integer part of the square root of n, and rem to the remainder of the operation. That is, rem will be equal to n-rop*rop, and it will be zero if n is a perfect square.

rop and rem must be distinct objects.

Parameters
  • rop – the first return value (i.e., the integer square root of n).

  • rem – the second return value (i.e., the remainder of the operation).

  • n – the argument.

Throws
  • std::domain_error – if n is negative.

  • std::invalid_argument – if rop and rem are the same object.

template<std::size_t SSize>
bool mppp::perfect_square_p(const mppp::integer<SSize> &n)

New in version 0.12.

Detect perfect square.

This function returns true if n is a perfect square, false otherwise.

Parameters

n – the argument.

Returns

true if n is a perfect square, false otherwise.

template<std::size_t SSize>
bool mppp::root(mppp::integer<SSize> &rop, const mppp::integer<SSize> &n, unsigned long m)

New in version 0.12.

Ternary \(m\)-th root.

This function will set rop to the truncated integer part of the \(m\)-th root of n. The return value will be true if the computation is exact, false otherwise.

Parameters
  • rop – the return value.

  • n – the argument.

  • m – the degree of the root.

Returns

true if the computation is exact, false otherwise.

Throws

std::domain_error – if m is even and n is negative, or if m is zero.

template<std::size_t SSize>
mppp::integer<SSize> mppp::root(const mppp::integer<SSize> &n, unsigned long m)

New in version 0.12.

Binary \(m\)-th root.

This function will return the truncated integer part of the \(m\)-th root of n.

Parameters
  • n – the argument.

  • m – the degree of the root.

Returns

the truncated integer part of the \(m\)-th root of n.

Throws

std::domain_error – if m is even and n is negative, or if m is zero.

template<std::size_t SSize>
void mppp::rootrem(mppp::integer<SSize> &rop, mppp::integer<SSize> &rem, const mppp::integer<SSize> &n, unsigned long m)

New in version 0.12.

\(m\)-th root with remainder.

This function will set rop to the truncated integer part of the \(m\)-th root of n, and rem to the remainder of the operation. That is, rem will be equal to n-rop**m, and it will be zero if n is a perfect power.

Parameters
  • rop – the first return value (i.e., the \(m\)-th root root of n).

  • rem – the second return value (i.e., the remainder of the operation).

  • n – the argument.

  • m – the degree of the root.

Throws

std::domain_error – if m is even and n is negative, or if m is zero.

template<std::size_t SSize>
bool mppp::perfect_power_p(const mppp::integer<SSize> &n)

New in version 0.12.

Detect perfect power.

This function will return true if n is a perfect power, that is, if there exist integers \(a\) and \(b\), with \(b>1\), such that n equals \(a^b\). Otherwise, the function will return false.

Parameters

n – the argument.

Returns

true if n is a perfect power, false otherwise.

Input/Output

template<std::size_t SSize>
std::ostream &mppp::operator<<(std::ostream &os, const mppp::integer<SSize> &n)

Stream insertion operator.

This function will direct to the output stream os the input integer n.

Parameters
  • os – the output stream.

  • n – the input integer.

Returns

a reference to os.

Throws
  • std::overflow_error – in case of (unlikely) overflow errors.

  • unspecified – any exception raised by the public interface of std::ostream or by memory allocation errors.

Serialisation

New in version 0.7.

template<std::size_t SSize>
std::size_t mppp::binary_size(const integer<SSize> &n)

Binary size of an integer.

This function is the free function equivalent of the mppp::integer::binary_size() method.

Return

the output of mppp::integer::binary_size() called on n.

Parameters
Exceptions

template<std::size_t SSize, IntegerBinarySaveDest<SSize> T>
std::size_t mppp::binary_save(const integer<SSize> &n, T &&dest)

Save an integer in binary format.

This function is the free function equivalent of all the mppp::integer::binary_save() overloads.

Return

the output of the invoked mppp::integer::binary_save() overload called on n with dest as argument.

Parameters
  • n: the target integer.

  • dest: the object into which the binary representation of n will be written.

Exceptions

template<std::size_t SSize, IntegerBinaryLoadSrc<SSize> T>
std::size_t mppp::binary_load(integer<SSize> &n, T &&src)

Load an integer in binary format.

This function is the free function equivalent of all the mppp::integer::binary_load() overloads.

Return

the output of the invoked mppp::integer::binary_load() overload called on n with src as argument.

Parameters
  • n: the target integer.

  • src: the object containing the integer binary representation that will be loaded into n.

Exceptions

Other

template<std::size_t SSize>
std::size_t mppp::hash(const integer<SSize> &n)

Hash value.

This function will return a hash value for n. The hash value depends only on the value of n (and not on its storage type).

A specialisation of the standard std::hash functor is also provided, so that it is possible to use integer in standard unordered associative containers out of the box.

Return

a hash value for n.

Parameters
  • n: the integer whose hash value will be computed.

void mppp::free_integer_caches()

Free the integer caches.

On some platforms, integer manages thread-local caches to speed-up the allocation/deallocation of small objects. These caches are automatically freed on program shutdown or when a thread exits. In certain situations, however, it may be desirable to manually free the memory in use by the caches before the program’s end or a thread’s exit. This function does exactly that.

On platforms where thread local storage is not supported, this funcion will be a no-op.

It is safe to call this function concurrently from different threads.

Mathematical operators

Overloaded operators are provided for convenience. Their interface is generic, and their implementation is typically built on top of basic functions.

template<std::size_t SSize>
integer<SSize> mppp::operator+(const integer<SSize> &n)

Identity operator.

Return

a copy of n.

Parameters
  • n: the integer that will be copied.

template<typename T, typename U>requires IntegerOpTypes<T, U> auto mppp::operator+(const T & op1, const U & op2)

Binary addition operator for integer.

The return type is determined as follows:

  • if the non-integer argument is a floating-point type F, then the type of the result is F; otherwise,

  • the type of the result is integer.

Return

op1 + op2.

Parameters
  • op1: the first summand.

  • op2: the second summand.

template<typename T, typename U>requires IntegerOpTypes<T, U> T& mppp::operator+=(T & rop, const U & op)

In-place addition operator.

Return

a reference to rop.

Parameters
  • rop: the augend.

  • op: the addend.

Exceptions
  • unspecified: any exception thrown by the assignment of a floating-point value to rop or by the conversion operator of integer.

template<std::size_t SSize>
integer<SSize> &mppp::operator++(integer<SSize> &n)

Prefix increment.

This operator will increment n by one.

Return

a reference to n after the increment.

Parameters
  • n: the integer that will be increased.

template<std::size_t SSize>
integer<SSize> mppp::operator++(integer<SSize> &n, int)

Suffix increment.

This operator will increment n by one and return a copy of n as it was before the increment.

Return

a copy of n before the increment.

Parameters
  • n: the integer that will be increased.

template<std::size_t SSize>
integer<SSize> mppp::operator-(const integer<SSize> &n)

Negated copy.

Return

a negated copy of n.

Parameters
  • n: the integer that will be negated.

template<typename T, typename U>requires IntegerOpTypes<T, U> auto mppp::operator-(const T & op1, const U & op2)

Binary subtraction operator for integer.

The return type is determined as follows:

  • if the non-integer argument is a floating-point type F, then the type of the result is F; otherwise,

  • the type of the result is integer.

Return

op1 - op2.

Parameters
  • op1: the first operand.

  • op2: the second operand.

template<typename T, typename U>requires IntegerOpTypes<T, U> T& mppp::operator-=(T & rop, const U & op)

In-place subtraction operator.

Return

a reference to rop.

Parameters
  • rop: the minuend.

  • op: the subtrahend.

Exceptions
  • unspecified: any exception thrown by the assignment of a floating-point value to rop or by the conversion operator of integer.

template<std::size_t SSize>
integer<SSize> &mppp::operator--(integer<SSize> &n)

Prefix decrement.

This operator will decrement n by one.

Return

a reference to n after the decrement.

Parameters
  • n: the integer that will be decreased.

template<std::size_t SSize>
integer<SSize> mppp::operator--(integer<SSize> &n, int)

Suffix decrement.

This operator will decrement n by one and return a copy of n as it was before the decrement.

Return

a copy of n before the decrement.

Parameters
  • n: the integer that will be decreased.

template<typename T, typename U>requires IntegerOpTypes<T, U> auto mppp::operator*(const T & op1, const U & op2)

Binary multiplication operator for integer.

The return type is determined as follows:

  • if the non-integer argument is a floating-point type F, then the type of the result is F; otherwise,

  • the type of the result is integer.

Return

op1 * op2.

Parameters
  • op1: the first factor.

  • op2: the second factor.

template<typename T, typename U>requires IntegerOpTypes<T, U> T& mppp::operator*=(T & rop, const U & op)

In-place multiplication operator.

Return

a reference to rop.

Parameters
  • rop: the multiplicand.

  • op: the multiplicator.

Exceptions
  • unspecified: any exception thrown by the assignment of a floating-point value to rop or by the conversion operator of integer.

template<typename T, typename U>requires IntegerOpTypes<T, U> auto mppp::operator/(const T & n, const U & d)

Binary division operator for integer.

The return type is determined as follows:

  • if the non-integer argument is a floating-point type F, then the type of the result is F; otherwise,

  • the type of the result is integer.

Return

n / d.

Parameters
  • n: the dividend.

  • d: the divisor.

Exceptions
  • zero_division_error: if d is zero and only integral types are involved in the division.

template<typename T, typename U>requires IntegerOpTypes<T, U> T& mppp::operator/=(T & rop, const U & op)

In-place division operator.

Return

a reference to rop.

Parameters
  • rop: the dividend.

  • op: the divisor.

Exceptions
  • zero_division_error: if op is zero and only integral types are involved in the division.

  • unspecified: any exception thrown by the assignment of a floating-point value to rop or by the conversion operator of integer.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> auto mppp::operator%(const T & n, const U & d)

Binary modulo operator for integer.

The return type is always an integer.

Return

n % d.

Parameters
  • n: the dividend.

  • d: the divisor.

Exceptions
  • zero_division_error: if d is zero.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> T& mppp::operator%=(T & rop, const U & op)

In-place modulo operator.

Return

a reference to rop.

Parameters
  • rop: the dividend.

  • op: the divisor.

Exceptions
  • zero_division_error: if op is zero.

  • unspecified: any exception thrown by the conversion operator of integer.

template<CppIntegralInteroperable T, std::size_t SSize>
integer<SSize> mppp::operator<<(const integer<SSize> &n, T s)

Binary left shift operator.

Return

n times 2**s.

Parameters
  • n: the multiplicand.

  • s: the bit shift value.

Exceptions
  • std::overflow_error: if s is negative or larger than an implementation-defined value.

template<CppIntegralInteroperable T, std::size_t SSize>
integer<SSize> &mppp::operator<<=(integer<SSize> &rop, T s)

In-place left shift operator.

Return

a reference to rop.

Parameters
  • rop: the multiplicand.

  • s: the bit shift value.

Exceptions
  • std::overflow_error: if s is negative or larger than an implementation-defined value.

template<CppIntegralInteroperable T, std::size_t SSize>
integer<SSize> mppp::operator>>(const integer<SSize> &n, T s)

Binary right shift operator.

Return

n divided 2**s.

Parameters
  • n: the dividend.

  • s: the bit shift value.

Exceptions
  • std::overflow_error: if s is negative or larger than an implementation-defined value.

template<CppIntegralInteroperable T, std::size_t SSize>
integer<SSize> &mppp::operator>>=(integer<SSize> &rop, T s)

In-place right shift operator.

Return

a reference to rop.

Parameters
  • rop: the dividend.

  • s: the bit shift value.

Exceptions
  • std::overflow_error: if s is negative or larger than an implementation-defined value.

template<typename T, typename U>requires IntegerOpTypes<T, U> bool mppp::operator==(const T & op1, const U & op2)

Equality operator.

Return

true if op1 == op2, false otherwise.

Parameters
  • op1: first argument.

  • op2: second argument.

template<typename T, typename U>requires IntegerOpTypes<T, U> bool mppp::operator!=(const T & op1, const U & op2)

Inequality operator.

Return

true if op1 != op2, false otherwise.

Parameters
  • op1: first argument.

  • op2: second argument.

template<typename T, typename U>requires IntegerOpTypes<T, U> bool mppp::operator<(const T & op1, const U & op2)

Less-than operator.

Return

true if op1 < op2, false otherwise.

Parameters
  • op1: first argument.

  • op2: second argument.

template<typename T, typename U>requires IntegerOpTypes<T, U> bool mppp::operator<=(const T & op1, const U & op2)

Less-than or equal operator.

Return

true if op1 <= op2, false otherwise.

Parameters
  • op1: first argument.

  • op2: second argument.

template<typename T, typename U>requires IntegerOpTypes<T, U> bool mppp::operator>(const T & op1, const U & op2)

Greater-than operator.

Return

true if op1 > op2, false otherwise.

Parameters
  • op1: first argument.

  • op2: second argument.

template<typename T, typename U>requires IntegerOpTypes<T, U> bool mppp::operator>=(const T & op1, const U & op2)

Greater-than or equal operator.

Return

true if op1 >= op2, false otherwise.

Parameters
  • op1: first argument.

  • op2: second argument.

template<std::size_t SSize>
integer<SSize> mppp::operator~(const integer<SSize> &op)

Unary bitwise NOT operator for integer.

This operator returns the bitwise NOT (i.e., the one’s complement) of op. Negative operands are treated as-if they were represented using two’s complement.

Return

the bitwise NOT of op.

Parameters
  • op: the operand.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> auto mppp::operator|(const T & op1, const U & op2)

Binary bitwise OR operator for integer.

This operator returns the bitwise OR of op1 and op2. Negative operands are treated as-if they were represented using two’s complement.

The return type is always an integer.

Return

the bitwise OR of op1 and op2.

Parameters
  • op1: the first operand.

  • op2: the second operand.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> T& mppp::operator|=(T & rop, const U & op)

In-place bitwise OR operator for integer.

This operator will set rop to the bitwise OR of rop and op. Negative operands are treated as-if they were represented using two’s complement.

Return

a reference to rop.

Parameters
  • rop: the first operand.

  • op: the second operand.

Exceptions
  • unspecified: any exception thrown by the conversion operator of integer.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> auto mppp::operator&(const T & op1, const U & op2)

Binary bitwise AND operator for integer.

This operator returns the bitwise AND of op1 and op2. Negative operands are treated as-if they were represented using two’s complement.

The return type is always an integer.

Return

the bitwise AND of op1 and op2.

Parameters
  • op1: the first operand.

  • op2: the second operand.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> T& mppp::operator&=(T & rop, const U & op)

In-place bitwise AND operator for integer.

This operator will set rop to the bitwise AND of rop and op. Negative operands are treated as-if they were represented using two’s complement.

Return

a reference to rop.

Parameters
  • rop: the first operand.

  • op: the second operand.

Exceptions
  • unspecified: any exception thrown by the conversion operator of integer.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> auto mppp::operator^(const T & op1, const U & op2)

Binary bitwise XOR operator for integer.

This operator returns the bitwise XOR of op1 and op2. Negative operands are treated as-if they were represented using two’s complement.

The return type is always an integer.

Return

the bitwise XOR of op1 and op2.

Parameters
  • op1: the first operand.

  • op2: the second operand.

template<typename T, typename U>requires IntegerIntegralOpTypes<T, U> T& mppp::operator^=(T & rop, const U & op)

In-place bitwise XOR operator for integer.

This operator will set rop to the bitwise XOR of rop and op. Negative operands are treated as-if they were represented using two’s complement.

Return

a reference to rop.

Parameters
  • rop: the first operand.

  • op: the second operand.

Exceptions
  • unspecified: any exception thrown by the conversion operator of integer.

Standard library specialisations

template<std::size_t SSize>
class std::hash<mppp::integer<SSize>>

Specialisation of std::hash for mppp::integer.

using argument_type = mppp::integer<SSize>
using result_type = std::size_t

Note

The argument_type and result_type type aliases are defined only until C++14.

std::size_t operator()(const mppp::integer<SSize> &n) const
Parameters

n – the input mppp::integer.

Returns

a hash value for n.