forked from OSchip/llvm-project
1199 lines
45 KiB
Markdown
1199 lines
45 KiB
Markdown
<!--
|
|
This file was generated from "doc.md.in" by mkdoc.py
|
|
DO NOT EDIT
|
|
-->
|
|
|
|
# User Documentation for the IMath Library
|
|
|
|
Author: [M. J. Fromberger](https://github.com/creachadair)
|
|
|
|
## Installation
|
|
|
|
1. Edit Makefile to select compiler and options. The default is to use gcc.
|
|
You may want to change CC to `clang` instead of `gcc` (and on macOS that
|
|
what you will get anyway), but you should be able to use the default GCC
|
|
settings for either.
|
|
|
|
By default, the Makefile assumes you can use 64-bit integer types, even
|
|
though they were not standard in ANSI C90. If you cannot, add
|
|
`-DUSE_32BIT_WORDS` to the compiler options.
|
|
|
|
2. Type `make` or `make test` to build the test driver and run the unit tests.
|
|
None of these should fail. If they do, see below for how you can report
|
|
bugs.
|
|
|
|
To build with debugging enabled (and optimization disabled), run `make
|
|
DEBUG=Y`. This sets the preprocessor macro `DEBUG` to 1, and several other
|
|
things (see Makefile for details).
|
|
|
|
To use the library in your code, include "imath.h" wherever you intend to use
|
|
the library's routines. The integer library is just a single source file, so
|
|
you can compile it into your project in whatever way makes sense. If you wish
|
|
to use rational arithmetic, you will also need to include "imrat.h".
|
|
|
|
## Background
|
|
|
|
The basic types defined by the imath library are `mpz_t`, an arbitrary
|
|
precision signed integer, and `mpq_t`, an arbitrary precision signed rational
|
|
number. The type `mp_int` is a pointer to an `mpz_t`, and `mp_rat` is a
|
|
pointer to an `mpq_t`.
|
|
|
|
Most of the functions in the imath library return a value of type `mp_result`.
|
|
This is a signed integer type which can be used to convey status information
|
|
and also return small values. Any negative value is considered to be a status
|
|
message. The following constants are defined for processing these:
|
|
|
|
| Status | Description |
|
|
| ----------- | -------------------------------------------- |
|
|
| `MP_OK` | operation successful, all is well (= 0) |
|
|
| `MP_FALSE` | boolean false (= `MP_OK`) |
|
|
| `MP_TRUE` | boolean true |
|
|
| `MP_MEMORY` | out of memory |
|
|
| `MP_RANGE` | parameter out of range |
|
|
| `MP_UNDEF` | result is undefined (e.g., division by zero) |
|
|
| `MP_TRUNC` | output value was truncated |
|
|
| `MP_BADARG` | an invalid parameter was passed |
|
|
|
|
If you obtain a zero or negative value of an `mp_result`, you can use the
|
|
`mp_error_string()` routine to obtain a pointer to a brief human-readable
|
|
string describing the error. These strings are statically allocated, so they
|
|
need not be freed by the caller; the same strings are re-used from call to
|
|
call.
|
|
|
|
Unless otherwise noted, it is legal to use the same parameter for both inputs
|
|
and output with most of the functions in this library. For example, you can
|
|
add a number to itself and replace the original by writing:
|
|
|
|
mp_int_add(a, a, a); /* a = a + a */
|
|
|
|
Any cases in which this is not legal will be noted in the function summaries
|
|
below (if you discover that this is not so, please report it as a bug; I will
|
|
fix either the function or the documentation :)
|
|
|
|
## The IMath API
|
|
|
|
Each of the API functions is documented here. The general format of the
|
|
entries is:
|
|
|
|
> ------------
|
|
> <pre>
|
|
> return_type function_name(parameters ...)
|
|
> </pre>
|
|
> - English description.
|
|
|
|
Unless otherwise noted, any API function that returns `mp_result` may be
|
|
expected to return `MP_OK`, `MP_BADARG`, or `MP_MEMORY`. Other return values
|
|
should be documented in the description. Please let me know if you discover
|
|
this is not the case.
|
|
|
|
The following macros are defined in "imath.h", to define the sizes of the
|
|
various data types used in the library:
|
|
|
|
| Constant | Description
|
|
| --------------- | ----------------------------------------
|
|
| `MP_DIGIT_BIT` | the number of bits in a single `mpz_t` digit.
|
|
| `MP_WORD_BIT` | the number of bits in a `mpz_t` word.
|
|
| `MP_SMALL_MIN` | the minimum value representable by an `mp_small`.
|
|
| `MP_SMALL_MAX` | the maximum value representable by an `mp_small`.
|
|
| `MP_USMALL_MAX` | the maximum value representable by an `mp_usmall`.
|
|
| `MP_MIN_RADIX` | the minimum radix accepted for base conversion.
|
|
| `MP_MAX_RADIX` | the maximum radix accepted for base conversion.
|
|
|
|
#### Initialization
|
|
|
|
An `mp_int` must be initialized before use. By default, an `mp_int` is
|
|
initialized with a certain minimum amount of storage for digits, and the
|
|
storage is expanded automatically as needed. To initialize an `mp_int`, use
|
|
the following functions:
|
|
|
|
------------
|
|
<a id="mp_int_init"></a><pre>
|
|
mp_result <a href="imath.h#L115">mp_int_init</a>(mp_int z);
|
|
</pre>
|
|
- Initializes `z` with 1-digit precision and sets it to zero. This function
|
|
cannot fail unless `z == NULL`.
|
|
|
|
------------
|
|
<a id="mp_int_alloc"></a><pre>
|
|
mp_int <a href="imath.h#L119">mp_int_alloc</a>(void);
|
|
</pre>
|
|
- Allocates a fresh zero-valued `mpz_t` on the heap, returning NULL in case
|
|
of error. The only possible error is out-of-memory.
|
|
|
|
------------
|
|
<a id="mp_int_init_size"></a><pre>
|
|
mp_result <a href="imath.h#L124">mp_int_init_size</a>(mp_int z, mp_size prec);
|
|
</pre>
|
|
- Initializes `z` with at least `prec` digits of storage, and sets it to
|
|
zero. If `prec` is zero, the default precision is used. In either case the
|
|
size is rounded up to the nearest multiple of the word size.
|
|
|
|
------------
|
|
<a id="mp_int_init_copy"></a><pre>
|
|
mp_result <a href="imath.h#L128">mp_int_init_copy</a>(mp_int z, mp_int old);
|
|
</pre>
|
|
- Initializes `z` to be a copy of an already-initialized value in `old`. The
|
|
new copy does not share storage with the original.
|
|
|
|
------------
|
|
<a id="mp_int_init_value"></a><pre>
|
|
mp_result <a href="imath.h#L131">mp_int_init_value</a>(mp_int z, mp_small value);
|
|
</pre>
|
|
- Initializes `z` to the specified signed `value` at default precision.
|
|
|
|
|
|
|
|
#### Cleanup
|
|
|
|
When you are finished with an `mp_int`, you must free the memory it uses:
|
|
|
|
------------
|
|
<a id="mp_int_clear"></a><pre>
|
|
void <a href="imath.h#L143">mp_int_clear</a>(mp_int z);
|
|
</pre>
|
|
- Releases the storage used by `z`.
|
|
|
|
------------
|
|
<a id="mp_int_free"></a><pre>
|
|
void <a href="imath.h#L147">mp_int_free</a>(mp_int z);
|
|
</pre>
|
|
- Releases the storage used by `z` and also `z` itself.
|
|
This should only be used for `z` allocated by `mp_int_alloc()`.
|
|
|
|
|
|
|
|
#### Setting Values
|
|
|
|
To set an `mp_int` which has already been initialized to a small integer value,
|
|
use:
|
|
|
|
------------
|
|
<a id="mp_int_set_value"></a><pre>
|
|
mp_result <a href="imath.h#L137">mp_int_set_value</a>(mp_int z, mp_small value);
|
|
</pre>
|
|
- Sets `z` to the value of the specified signed `value`.
|
|
|
|
------------
|
|
<a id="mp_int_set_uvalue"></a><pre>
|
|
mp_result <a href="imath.h#L140">mp_int_set_uvalue</a>(mp_int z, mp_usmall uvalue);
|
|
</pre>
|
|
- Sets `z` to the value of the specified unsigned `value`.
|
|
|
|
|
|
|
|
To copy one initialized `mp_int` to another, use:
|
|
|
|
------------
|
|
<a id="mp_int_copy"></a><pre>
|
|
mp_result <a href="imath.h#L151">mp_int_copy</a>(mp_int a, mp_int c);
|
|
</pre>
|
|
- Replaces the value of `c` with a copy of the value of `a`. No new memory is
|
|
allocated unless `a` has more significant digits than `c` has allocated.
|
|
|
|
|
|
|
|
### Arithmetic Functions
|
|
|
|
------------
|
|
<a id="mp_int_is_odd"></a><pre>
|
|
static inline bool <a href="imath.h#L108">mp_int_is_odd</a>(mp_int z);
|
|
</pre>
|
|
- Reports whether `z` is odd, having remainder 1 when divided by 2.
|
|
|
|
------------
|
|
<a id="mp_int_is_even"></a><pre>
|
|
static inline bool <a href="imath.h#L111">mp_int_is_even</a>(mp_int z);
|
|
</pre>
|
|
- Reports whether `z` is even, having remainder 0 when divided by 2.
|
|
|
|
------------
|
|
<a id="mp_int_zero"></a><pre>
|
|
void <a href="imath.h#L157">mp_int_zero</a>(mp_int z);
|
|
</pre>
|
|
- Sets `z` to zero. The allocated storage of `z` is not changed.
|
|
|
|
------------
|
|
<a id="mp_int_abs"></a><pre>
|
|
mp_result <a href="imath.h#L160">mp_int_abs</a>(mp_int a, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the absolute value of `a`.
|
|
|
|
------------
|
|
<a id="mp_int_neg"></a><pre>
|
|
mp_result <a href="imath.h#L163">mp_int_neg</a>(mp_int a, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the additive inverse (negation) of `a`.
|
|
|
|
------------
|
|
<a id="mp_int_add"></a><pre>
|
|
mp_result <a href="imath.h#L166">mp_int_add</a>(mp_int a, mp_int b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the sum of `a` and `b`.
|
|
|
|
------------
|
|
<a id="mp_int_add_value"></a><pre>
|
|
mp_result <a href="imath.h#L169">mp_int_add_value</a>(mp_int a, mp_small value, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the sum of `a` and `value`.
|
|
|
|
------------
|
|
<a id="mp_int_sub"></a><pre>
|
|
mp_result <a href="imath.h#L172">mp_int_sub</a>(mp_int a, mp_int b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the difference of `a` less `b`.
|
|
|
|
------------
|
|
<a id="mp_int_sub_value"></a><pre>
|
|
mp_result <a href="imath.h#L175">mp_int_sub_value</a>(mp_int a, mp_small value, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the difference of `a` less `value`.
|
|
|
|
------------
|
|
<a id="mp_int_mul"></a><pre>
|
|
mp_result <a href="imath.h#L178">mp_int_mul</a>(mp_int a, mp_int b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the product of `a` and `b`.
|
|
|
|
------------
|
|
<a id="mp_int_mul_value"></a><pre>
|
|
mp_result <a href="imath.h#L181">mp_int_mul_value</a>(mp_int a, mp_small value, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the product of `a` and `value`.
|
|
|
|
------------
|
|
<a id="mp_int_mul_pow2"></a><pre>
|
|
mp_result <a href="imath.h#L184">mp_int_mul_pow2</a>(mp_int a, mp_small p2, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the product of `a` and `2^p2`. Requires `p2 >= 0`.
|
|
|
|
------------
|
|
<a id="mp_int_sqr"></a><pre>
|
|
mp_result <a href="imath.h#L187">mp_int_sqr</a>(mp_int a, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the square of `a`.
|
|
|
|
------------
|
|
<a id="mp_int_root"></a><pre>
|
|
mp_result <a href="imath.h#L306">mp_int_root</a>(mp_int a, mp_small b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the greatest integer not less than the `b`th root of `a`,
|
|
using Newton's root-finding algorithm.
|
|
It returns `MP_UNDEF` if `a < 0` and `b` is even.
|
|
|
|
------------
|
|
<a id="mp_int_sqrt"></a><pre>
|
|
static inline mp_result <a href="imath.h#L310">mp_int_sqrt</a>(mp_int a, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the greatest integer not less than the square root of `a`.
|
|
This is a special case of `mp_int_root()`.
|
|
|
|
------------
|
|
<a id="mp_int_div"></a><pre>
|
|
mp_result <a href="imath.h#L195">mp_int_div</a>(mp_int a, mp_int b, mp_int q, mp_int r);
|
|
</pre>
|
|
- Sets `q` and `r` to the quotent and remainder of `a / b`. Division by
|
|
powers of 2 is detected and handled efficiently. The remainder is pinned
|
|
to `0 <= r < b`.
|
|
|
|
Either of `q` or `r` may be NULL, but not both, and `q` and `r` may not
|
|
point to the same value.
|
|
|
|
------------
|
|
<a id="mp_int_div_value"></a><pre>
|
|
mp_result <a href="imath.h#L200">mp_int_div_value</a>(mp_int a, mp_small value, mp_int q, mp_small *r);
|
|
</pre>
|
|
- Sets `q` and `*r` to the quotent and remainder of `a / value`. Division by
|
|
powers of 2 is detected and handled efficiently. The remainder is pinned to
|
|
`0 <= *r < b`. Either of `q` or `r` may be NULL.
|
|
|
|
------------
|
|
<a id="mp_int_div_pow2"></a><pre>
|
|
mp_result <a href="imath.h#L206">mp_int_div_pow2</a>(mp_int a, mp_small p2, mp_int q, mp_int r);
|
|
</pre>
|
|
- Sets `q` and `r` to the quotient and remainder of `a / 2^p2`. This is a
|
|
special case for division by powers of two that is more efficient than
|
|
using ordinary division. Note that `mp_int_div()` will automatically handle
|
|
this case, this function is for cases where you have only the exponent.
|
|
|
|
------------
|
|
<a id="mp_int_mod"></a><pre>
|
|
mp_result <a href="imath.h#L210">mp_int_mod</a>(mp_int a, mp_int m, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the remainder of `a / m`.
|
|
The remainder is pinned to `0 <= c < m`.
|
|
|
|
------------
|
|
<a id="mp_int_mod_value"></a><pre>
|
|
static inline mp_result <a href="imath.h#L226">mp_int_mod_value</a>(mp_int a, mp_small value, mp_small* r);
|
|
</pre>
|
|
- Sets `*r` to the remainder of `a / value`.
|
|
The remainder is pinned to `0 <= r < value`.
|
|
|
|
------------
|
|
<a id="mp_int_expt"></a><pre>
|
|
mp_result <a href="imath.h#L214">mp_int_expt</a>(mp_int a, mp_small b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the value of `a` raised to the `b` power.
|
|
It returns `MP_RANGE` if `b < 0`.
|
|
|
|
------------
|
|
<a id="mp_int_expt_value"></a><pre>
|
|
mp_result <a href="imath.h#L218">mp_int_expt_value</a>(mp_small a, mp_small b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the value of `a` raised to the `b` power.
|
|
It returns `MP_RANGE` if `b < 0`.
|
|
|
|
------------
|
|
<a id="mp_int_expt_full"></a><pre>
|
|
mp_result <a href="imath.h#L222">mp_int_expt_full</a>(mp_int a, mp_int b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the value of `a` raised to the `b` power.
|
|
It returns `MP_RANGE`) if `b < 0`.
|
|
|
|
|
|
|
|
### Comparison Functions
|
|
|
|
Unless otherwise specified, comparison between values `x` and `y` returns a
|
|
**comparator**, an integer value < 0 if `x` is less than `y`, 0 if `x` is equal
|
|
to `y`, and > 0 if `x` is greater than `y`.
|
|
|
|
------------
|
|
<a id="mp_int_compare"></a><pre>
|
|
int <a href="imath.h#L232">mp_int_compare</a>(mp_int a, mp_int b);
|
|
</pre>
|
|
- Returns the comparator of `a` and `b`.
|
|
|
|
------------
|
|
<a id="mp_int_compare_unsigned"></a><pre>
|
|
int <a href="imath.h#L236">mp_int_compare_unsigned</a>(mp_int a, mp_int b);
|
|
</pre>
|
|
- Returns the comparator of the magnitudes of `a` and `b`, disregarding their
|
|
signs. Neither `a` nor `b` is modified by the comparison.
|
|
|
|
------------
|
|
<a id="mp_int_compare_zero"></a><pre>
|
|
int <a href="imath.h#L239">mp_int_compare_zero</a>(mp_int z);
|
|
</pre>
|
|
- Returns the comparator of `z` and zero.
|
|
|
|
------------
|
|
<a id="mp_int_compare_value"></a><pre>
|
|
int <a href="imath.h#L242">mp_int_compare_value</a>(mp_int z, mp_small v);
|
|
</pre>
|
|
- Returns the comparator of `z` and the signed value `v`.
|
|
|
|
------------
|
|
<a id="mp_int_compare_uvalue"></a><pre>
|
|
int <a href="imath.h#L245">mp_int_compare_uvalue</a>(mp_int z, mp_usmall uv);
|
|
</pre>
|
|
- Returns the comparator of `z` and the unsigned value `uv`.
|
|
|
|
------------
|
|
<a id="mp_int_divisible_value"></a><pre>
|
|
bool <a href="imath.h#L248">mp_int_divisible_value</a>(mp_int a, mp_small v);
|
|
</pre>
|
|
- Reports whether `a` is divisible by `v`.
|
|
|
|
------------
|
|
<a id="mp_int_is_pow2"></a><pre>
|
|
int <a href="imath.h#L252">mp_int_is_pow2</a>(mp_int z);
|
|
</pre>
|
|
- Returns `k >= 0` such that `z` is `2^k`, if such a `k` exists. If no such
|
|
`k` exists, the function returns -1.
|
|
|
|
|
|
|
|
### Modular Operations
|
|
|
|
------------
|
|
<a id="mp_int_exptmod"></a><pre>
|
|
mp_result <a href="imath.h#L256">mp_int_exptmod</a>(mp_int a, mp_int b, mp_int m, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`.
|
|
It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`.
|
|
|
|
------------
|
|
<a id="mp_int_exptmod_evalue"></a><pre>
|
|
mp_result <a href="imath.h#L260">mp_int_exptmod_evalue</a>(mp_int a, mp_small value, mp_int m, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the value of `a` raised to the `value` power, modulo `m`.
|
|
It returns `MP_RANGE` if `value < 0` or `MP_UNDEF` if `m == 0`.
|
|
|
|
------------
|
|
<a id="mp_int_exptmod_bvalue"></a><pre>
|
|
mp_result <a href="imath.h#L264">mp_int_exptmod_bvalue</a>(mp_small value, mp_int b, mp_int m, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the value of `value` raised to the `b` power, modulo `m`.
|
|
It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`.
|
|
|
|
------------
|
|
<a id="mp_int_exptmod_known"></a><pre>
|
|
mp_result <a href="imath.h#L271">mp_int_exptmod_known</a>(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`,
|
|
given a precomputed reduction constant `mu` defined for Barrett's modular
|
|
reduction algorithm.
|
|
|
|
It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`.
|
|
|
|
------------
|
|
<a id="mp_int_redux_const"></a><pre>
|
|
mp_result <a href="imath.h#L275">mp_int_redux_const</a>(mp_int m, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the reduction constant for Barrett reduction by modulus `m`.
|
|
Requires that `c` and `m` point to distinct locations.
|
|
|
|
------------
|
|
<a id="mp_int_invmod"></a><pre>
|
|
mp_result <a href="imath.h#L282">mp_int_invmod</a>(mp_int a, mp_int m, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the multiplicative inverse of `a` modulo `m`, if it exists.
|
|
The least non-negative representative of the congruence class is computed.
|
|
|
|
It returns `MP_UNDEF` if the inverse does not exist, or `MP_RANGE` if `a ==
|
|
0` or `m <= 0`.
|
|
|
|
------------
|
|
<a id="mp_int_gcd"></a><pre>
|
|
mp_result <a href="imath.h#L288">mp_int_gcd</a>(mp_int a, mp_int b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the greatest common divisor of `a` and `b`.
|
|
|
|
It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a`
|
|
and `b` are both zero.
|
|
|
|
------------
|
|
<a id="mp_int_egcd"></a><pre>
|
|
mp_result <a href="imath.h#L295">mp_int_egcd</a>(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y);
|
|
</pre>
|
|
- Sets `c` to the greatest common divisor of `a` and `b`, and sets `x` and
|
|
`y` to values satisfying Bezout's identity `gcd(a, b) = ax + by`.
|
|
|
|
It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a`
|
|
and `b` are both zero.
|
|
|
|
------------
|
|
<a id="mp_int_lcm"></a><pre>
|
|
mp_result <a href="imath.h#L301">mp_int_lcm</a>(mp_int a, mp_int b, mp_int c);
|
|
</pre>
|
|
- Sets `c` to the least common multiple of `a` and `b`.
|
|
|
|
It returns `MP_UNDEF` if the LCM is undefined, such as for example if `a`
|
|
and `b` are both zero.
|
|
|
|
|
|
|
|
### Conversion of Values
|
|
|
|
------------
|
|
<a id="mp_int_to_int"></a><pre>
|
|
mp_result <a href="imath.h#L315">mp_int_to_int</a>(mp_int z, mp_small *out);
|
|
</pre>
|
|
- Returns `MP_OK` if `z` is representable as `mp_small`, else `MP_RANGE`.
|
|
If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`.
|
|
|
|
------------
|
|
<a id="mp_int_to_uint"></a><pre>
|
|
mp_result <a href="imath.h#L319">mp_int_to_uint</a>(mp_int z, mp_usmall *out);
|
|
</pre>
|
|
- Returns `MP_OK` if `z` is representable as `mp_usmall`, or `MP_RANGE`.
|
|
If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`.
|
|
|
|
------------
|
|
<a id="mp_int_to_string"></a><pre>
|
|
mp_result <a href="imath.h#L327">mp_int_to_string</a>(mp_int z, mp_size radix, char *str, int limit);
|
|
</pre>
|
|
- Converts `z` to a zero-terminated string of characters in the specified
|
|
`radix`, writing at most `limit` characters to `str` including the
|
|
terminating NUL value. A leading `-` is used to indicate a negative value.
|
|
|
|
Returns `MP_TRUNC` if `limit` was to small to write all of `z`.
|
|
Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
|
|
|
|
------------
|
|
<a id="mp_int_string_len"></a><pre>
|
|
mp_result <a href="imath.h#L332">mp_int_string_len</a>(mp_int z, mp_size radix);
|
|
</pre>
|
|
- Reports the minimum number of characters required to represent `z` as a
|
|
zero-terminated string in the given `radix`.
|
|
Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
|
|
|
|
------------
|
|
<a id="mp_int_read_string"></a><pre>
|
|
mp_result <a href="imath.h#L347">mp_int_read_string</a>(mp_int z, mp_size radix, const char *str);
|
|
</pre>
|
|
- Reads a string of ASCII digits in the specified `radix` from the zero
|
|
terminated `str` provided into `z`. For values of `radix > 10`, the letters
|
|
`A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect
|
|
to case.
|
|
|
|
Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a
|
|
sign flag. Processing stops when a NUL or any other character out of range
|
|
for a digit in the given radix is encountered.
|
|
|
|
If the whole string was consumed, `MP_OK` is returned; otherwise
|
|
`MP_TRUNC`. is returned.
|
|
|
|
Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
|
|
|
|
------------
|
|
<a id="mp_int_read_cstring"></a><pre>
|
|
mp_result <a href="imath.h#L365">mp_int_read_cstring</a>(mp_int z, mp_size radix, const char *str, char **end);
|
|
</pre>
|
|
- Reads a string of ASCII digits in the specified `radix` from the zero
|
|
terminated `str` provided into `z`. For values of `radix > 10`, the letters
|
|
`A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect
|
|
to case.
|
|
|
|
Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a
|
|
sign flag. Processing stops when a NUL or any other character out of range
|
|
for a digit in the given radix is encountered.
|
|
|
|
If the whole string was consumed, `MP_OK` is returned; otherwise
|
|
`MP_TRUNC`. is returned. If `end` is not NULL, `*end` is set to point to
|
|
the first unconsumed byte of the input string (the NUL byte if the whole
|
|
string was consumed). This emulates the behavior of the standard C
|
|
`strtol()` function.
|
|
|
|
Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
|
|
|
|
------------
|
|
<a id="mp_int_count_bits"></a><pre>
|
|
mp_result <a href="imath.h#L368">mp_int_count_bits</a>(mp_int z);
|
|
</pre>
|
|
- Returns the number of significant bits in `z`.
|
|
|
|
------------
|
|
<a id="mp_int_to_binary"></a><pre>
|
|
mp_result <a href="imath.h#L383">mp_int_to_binary</a>(mp_int z, unsigned char *buf, int limit);
|
|
</pre>
|
|
- Converts `z` to 2's complement binary, writing at most `limit` bytes into
|
|
the given `buf`. Returns `MP_TRUNC` if the buffer limit was too small to
|
|
contain the whole value. If this occurs, the contents of buf will be
|
|
effectively garbage, as the function uses the buffer as scratch space.
|
|
|
|
The binary representation of `z` is in base-256 with digits ordered from
|
|
most significant to least significant (network byte ordering). The
|
|
high-order bit of the first byte is set for negative values, clear for
|
|
non-negative values.
|
|
|
|
As a result, non-negative values will be padded with a leading zero byte if
|
|
the high-order byte of the base-256 magnitude is set. This extra byte is
|
|
accounted for by the `mp_int_binary_len()` function.
|
|
|
|
------------
|
|
<a id="mp_int_read_binary"></a><pre>
|
|
mp_result <a href="imath.h#L388">mp_int_read_binary</a>(mp_int z, unsigned char *buf, int len);
|
|
</pre>
|
|
- Reads a 2's complement binary value from `buf` into `z`, where `len` is the
|
|
length of the buffer. The contents of `buf` may be overwritten during
|
|
processing, although they will be restored when the function returns.
|
|
|
|
------------
|
|
<a id="mp_int_binary_len"></a><pre>
|
|
mp_result <a href="imath.h#L391">mp_int_binary_len</a>(mp_int z);
|
|
</pre>
|
|
- Returns the number of bytes to represent `z` in 2's complement binary.
|
|
|
|
------------
|
|
<a id="mp_int_to_unsigned"></a><pre>
|
|
mp_result <a href="imath.h#L402">mp_int_to_unsigned</a>(mp_int z, unsigned char *buf, int limit);
|
|
</pre>
|
|
- Converts the magnitude of `z` to unsigned binary, writing at most `limit`
|
|
bytes into the given `buf`. The sign of `z` is ignored, but `z` is not
|
|
modified. Returns `MP_TRUNC` if the buffer limit was too small to contain
|
|
the whole value. If this occurs, the contents of `buf` will be effectively
|
|
garbage, as the function uses the buffer as scratch space during
|
|
conversion.
|
|
|
|
The binary representation of `z` is in base-256 with digits ordered from
|
|
most significant to least significant (network byte ordering).
|
|
|
|
------------
|
|
<a id="mp_int_read_unsigned"></a><pre>
|
|
mp_result <a href="imath.h#L407">mp_int_read_unsigned</a>(mp_int z, unsigned char *buf, int len);
|
|
</pre>
|
|
- Reads an unsigned binary value from `buf` into `z`, where `len` is the
|
|
length of the buffer. The contents of `buf` are not modified during
|
|
processing.
|
|
|
|
------------
|
|
<a id="mp_int_unsigned_len"></a><pre>
|
|
mp_result <a href="imath.h#L411">mp_int_unsigned_len</a>(mp_int z);
|
|
</pre>
|
|
- Returns the number of bytes required to represent `z` as an unsigned binary
|
|
value in base 256.
|
|
|
|
|
|
|
|
### Other Functions
|
|
|
|
Ordinarily, integer multiplication and squaring are done using the simple
|
|
quadratic "schoolbook" algorithm. However, for sufficiently large values,
|
|
there is a more efficient algorithm usually attributed to Karatsuba and Ofman
|
|
that is usually faster. See Knuth Vol. 2 for more details about how this
|
|
algorithm works.
|
|
|
|
The breakpoint between the "normal" and the recursive algorithm is controlled
|
|
by a static digit threshold defined in `imath.c`. Values with fewer significant
|
|
digits use the standard algorithm. This value can be modified by calling
|
|
`mp_int_multiply_threshold(n)`. The `imtimer` program and the
|
|
`findthreshold.py` script (Python) can help you find a suitable value for for
|
|
your particular platform.
|
|
|
|
------------
|
|
<a id="mp_error_string"></a><pre>
|
|
const char *<a href="imath.h#L416">mp_error_string</a>(mp_result res);
|
|
</pre>
|
|
- Returns a pointer to a brief, human-readable, zero-terminated string
|
|
describing `res`. The returned string is statically allocated and must not
|
|
be freed by the caller.
|
|
|
|
|
|
|
|
## Rational Arithmetic
|
|
|
|
------------
|
|
<a id="mp_rat_init"></a><pre>
|
|
mp_result <a href="imrat.h#L59">mp_rat_init</a>(mp_rat r);
|
|
</pre>
|
|
- Initializes `r` with 1-digit precision and sets it to zero. This function
|
|
cannot fail unless `r` is NULL.
|
|
|
|
------------
|
|
<a id="mp_rat_alloc"></a><pre>
|
|
mp_rat <a href="imrat.h#L63">mp_rat_alloc</a>(void);
|
|
</pre>
|
|
- Allocates a fresh zero-valued `mpq_t` on the heap, returning NULL in case
|
|
of error. The only possible error is out-of-memory.
|
|
|
|
------------
|
|
<a id="mp_rat_reduce"></a><pre>
|
|
mp_result <a href="imrat.h#L69">mp_rat_reduce</a>(mp_rat r);
|
|
</pre>
|
|
- Reduces `r` in-place to lowest terms and canonical form.
|
|
|
|
Zero is represented as 0/1, one as 1/1, and signs are adjusted so that the
|
|
sign of the value is carried by the numerator.
|
|
|
|
------------
|
|
<a id="mp_rat_init_size"></a><pre>
|
|
mp_result <a href="imrat.h#L76">mp_rat_init_size</a>(mp_rat r, mp_size n_prec, mp_size d_prec);
|
|
</pre>
|
|
- Initializes `r` with at least `n_prec` digits of storage for the numerator
|
|
and `d_prec` digits of storage for the denominator, and value zero.
|
|
|
|
If either precision is zero, the default precision is used, rounded up to
|
|
the nearest word size.
|
|
|
|
------------
|
|
<a id="mp_rat_init_copy"></a><pre>
|
|
mp_result <a href="imrat.h#L80">mp_rat_init_copy</a>(mp_rat r, mp_rat old);
|
|
</pre>
|
|
- Initializes `r` to be a copy of an already-initialized value in `old`. The
|
|
new copy does not share storage with the original.
|
|
|
|
------------
|
|
<a id="mp_rat_set_value"></a><pre>
|
|
mp_result <a href="imrat.h#L84">mp_rat_set_value</a>(mp_rat r, mp_small numer, mp_small denom);
|
|
</pre>
|
|
- Sets the value of `r` to the ratio of signed `numer` to signed `denom`. It
|
|
returns `MP_UNDEF` if `denom` is zero.
|
|
|
|
------------
|
|
<a id="mp_rat_set_uvalue"></a><pre>
|
|
mp_result <a href="imrat.h#L88">mp_rat_set_uvalue</a>(mp_rat r, mp_usmall numer, mp_usmall denom);
|
|
</pre>
|
|
- Sets the value of `r` to the ratio of unsigned `numer` to unsigned
|
|
`denom`. It returns `MP_UNDEF` if `denom` is zero.
|
|
|
|
------------
|
|
<a id="mp_rat_clear"></a><pre>
|
|
void <a href="imrat.h#L91">mp_rat_clear</a>(mp_rat r);
|
|
</pre>
|
|
- Releases the storage used by `r`.
|
|
|
|
------------
|
|
<a id="mp_rat_free"></a><pre>
|
|
void <a href="imrat.h#L95">mp_rat_free</a>(mp_rat r);
|
|
</pre>
|
|
- Releases the storage used by `r` and also `r` itself.
|
|
This should only be used for `r` allocated by `mp_rat_alloc()`.
|
|
|
|
------------
|
|
<a id="mp_rat_numer"></a><pre>
|
|
mp_result <a href="imrat.h#L98">mp_rat_numer</a>(mp_rat r, mp_int z);
|
|
</pre>
|
|
- Sets `z` to a copy of the numerator of `r`.
|
|
|
|
------------
|
|
<a id="mp_rat_numer_ref"></a><pre>
|
|
mp_int <a href="imrat.h#L101">mp_rat_numer_ref</a>(mp_rat r);
|
|
</pre>
|
|
- Returns a pointer to the numerator of `r`.
|
|
|
|
------------
|
|
<a id="mp_rat_denom"></a><pre>
|
|
mp_result <a href="imrat.h#L104">mp_rat_denom</a>(mp_rat r, mp_int z);
|
|
</pre>
|
|
- Sets `z` to a copy of the denominator of `r`.
|
|
|
|
------------
|
|
<a id="mp_rat_denom_ref"></a><pre>
|
|
mp_int <a href="imrat.h#L107">mp_rat_denom_ref</a>(mp_rat r);
|
|
</pre>
|
|
- Returns a pointer to the denominator of `r`.
|
|
|
|
------------
|
|
<a id="mp_rat_sign"></a><pre>
|
|
mp_sign <a href="imrat.h#L110">mp_rat_sign</a>(mp_rat r);
|
|
</pre>
|
|
- Reports the sign of `r`.
|
|
|
|
------------
|
|
<a id="mp_rat_copy"></a><pre>
|
|
mp_result <a href="imrat.h#L115">mp_rat_copy</a>(mp_rat a, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to a copy of the value of `a`. No new memory is allocated unless a
|
|
term of `a` has more significant digits than the corresponding term of `c`
|
|
has allocated.
|
|
|
|
------------
|
|
<a id="mp_rat_zero"></a><pre>
|
|
void <a href="imrat.h#L118">mp_rat_zero</a>(mp_rat r);
|
|
</pre>
|
|
- Sets `r` to zero. The allocated storage of `r` is not changed.
|
|
|
|
------------
|
|
<a id="mp_rat_abs"></a><pre>
|
|
mp_result <a href="imrat.h#L121">mp_rat_abs</a>(mp_rat a, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the absolute value of `a`.
|
|
|
|
------------
|
|
<a id="mp_rat_neg"></a><pre>
|
|
mp_result <a href="imrat.h#L124">mp_rat_neg</a>(mp_rat a, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the absolute value of `a`.
|
|
|
|
------------
|
|
<a id="mp_rat_recip"></a><pre>
|
|
mp_result <a href="imrat.h#L128">mp_rat_recip</a>(mp_rat a, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the reciprocal of `a` if the reciprocal is defined.
|
|
It returns `MP_UNDEF` if `a` is zero.
|
|
|
|
------------
|
|
<a id="mp_rat_add"></a><pre>
|
|
mp_result <a href="imrat.h#L131">mp_rat_add</a>(mp_rat a, mp_rat b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the sum of `a` and `b`.
|
|
|
|
------------
|
|
<a id="mp_rat_sub"></a><pre>
|
|
mp_result <a href="imrat.h#L134">mp_rat_sub</a>(mp_rat a, mp_rat b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the difference of `a` less `b`.
|
|
|
|
------------
|
|
<a id="mp_rat_mul"></a><pre>
|
|
mp_result <a href="imrat.h#L137">mp_rat_mul</a>(mp_rat a, mp_rat b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the product of `a` and `b`.
|
|
|
|
------------
|
|
<a id="mp_rat_div"></a><pre>
|
|
mp_result <a href="imrat.h#L141">mp_rat_div</a>(mp_rat a, mp_rat b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the ratio `a / b` if that ratio is defined.
|
|
It returns `MP_UNDEF` if `b` is zero.
|
|
|
|
------------
|
|
<a id="mp_rat_add_int"></a><pre>
|
|
mp_result <a href="imrat.h#L144">mp_rat_add_int</a>(mp_rat a, mp_int b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the sum of `a` and integer `b`.
|
|
|
|
------------
|
|
<a id="mp_rat_sub_int"></a><pre>
|
|
mp_result <a href="imrat.h#L147">mp_rat_sub_int</a>(mp_rat a, mp_int b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the difference of `a` less integer `b`.
|
|
|
|
------------
|
|
<a id="mp_rat_mul_int"></a><pre>
|
|
mp_result <a href="imrat.h#L150">mp_rat_mul_int</a>(mp_rat a, mp_int b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the product of `a` and integer `b`.
|
|
|
|
------------
|
|
<a id="mp_rat_div_int"></a><pre>
|
|
mp_result <a href="imrat.h#L154">mp_rat_div_int</a>(mp_rat a, mp_int b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the ratio `a / b` if that ratio is defined.
|
|
It returns `MP_UNDEF` if `b` is zero.
|
|
|
|
------------
|
|
<a id="mp_rat_expt"></a><pre>
|
|
mp_result <a href="imrat.h#L158">mp_rat_expt</a>(mp_rat a, mp_small b, mp_rat c);
|
|
</pre>
|
|
- Sets `c` to the value of `a` raised to the `b` power.
|
|
It returns `MP_RANGE` if `b < 0`.
|
|
|
|
------------
|
|
<a id="mp_rat_compare"></a><pre>
|
|
int <a href="imrat.h#L161">mp_rat_compare</a>(mp_rat a, mp_rat b);
|
|
</pre>
|
|
- Returns the comparator of `a` and `b`.
|
|
|
|
------------
|
|
<a id="mp_rat_compare_unsigned"></a><pre>
|
|
int <a href="imrat.h#L165">mp_rat_compare_unsigned</a>(mp_rat a, mp_rat b);
|
|
</pre>
|
|
- Returns the comparator of the magnitudes of `a` and `b`, disregarding their
|
|
signs. Neither `a` nor `b` is modified by the comparison.
|
|
|
|
------------
|
|
<a id="mp_rat_compare_zero"></a><pre>
|
|
int <a href="imrat.h#L168">mp_rat_compare_zero</a>(mp_rat r);
|
|
</pre>
|
|
- Returns the comparator of `r` and zero.
|
|
|
|
------------
|
|
<a id="mp_rat_compare_value"></a><pre>
|
|
int <a href="imrat.h#L172">mp_rat_compare_value</a>(mp_rat r, mp_small n, mp_small d);
|
|
</pre>
|
|
- Returns the comparator of `r` and the signed ratio `n / d`.
|
|
It returns `MP_UNDEF` if `d` is zero.
|
|
|
|
------------
|
|
<a id="mp_rat_is_integer"></a><pre>
|
|
bool <a href="imrat.h#L175">mp_rat_is_integer</a>(mp_rat r);
|
|
</pre>
|
|
- Reports whether `r` is an integer, having canonical denominator 1.
|
|
|
|
------------
|
|
<a id="mp_rat_to_ints"></a><pre>
|
|
mp_result <a href="imrat.h#L180">mp_rat_to_ints</a>(mp_rat r, mp_small *num, mp_small *den);
|
|
</pre>
|
|
- Reports whether the numerator and denominator of `r` can be represented as
|
|
small signed integers, and if so stores the corresponding values to `num`
|
|
and `den`. It returns `MP_RANGE` if either cannot be so represented.
|
|
|
|
------------
|
|
<a id="mp_rat_to_string"></a><pre>
|
|
mp_result <a href="imrat.h#L186">mp_rat_to_string</a>(mp_rat r, mp_size radix, char *str, int limit);
|
|
</pre>
|
|
- Converts `r` to a zero-terminated string of the format `"n/d"` with `n` and
|
|
`d` in the specified radix and writing no more than `limit` bytes to the
|
|
given output buffer `str`. The output of the numerator includes a sign flag
|
|
if `r` is negative. Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
|
|
|
|
------------
|
|
<a id="mp_rat_to_decimal"></a><pre>
|
|
mp_result <a href="imrat.h#L215">mp_rat_to_decimal</a>(mp_rat r, mp_size radix, mp_size prec, mp_round_mode round, char *str, int limit);
|
|
</pre>
|
|
- Converts the value of `r` to a string in decimal-point notation with the
|
|
specified radix, writing no more than `limit` bytes of data to the given
|
|
output buffer. It generates `prec` digits of precision, and requires
|
|
`MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
|
|
|
|
Ratios usually must be rounded when they are being converted for output as
|
|
a decimal value. There are four rounding modes currently supported:
|
|
|
|
```
|
|
MP_ROUND_DOWN
|
|
Truncates the value toward zero.
|
|
Example: 12.009 to 2dp becomes 12.00
|
|
```
|
|
|
|
```
|
|
MP_ROUND_UP
|
|
Rounds the value away from zero:
|
|
Example: 12.001 to 2dp becomes 12.01, but
|
|
12.000 to 2dp remains 12.00
|
|
```
|
|
|
|
```
|
|
MP_ROUND_HALF_DOWN
|
|
Rounds the value to nearest digit, half goes toward zero.
|
|
Example: 12.005 to 2dp becomes 12.00, but
|
|
12.006 to 2dp becomes 12.01
|
|
```
|
|
|
|
```
|
|
MP_ROUND_HALF_UP
|
|
Rounds the value to nearest digit, half rounds upward.
|
|
Example: 12.005 to 2dp becomes 12.01, but
|
|
12.004 to 2dp becomes 12.00
|
|
```
|
|
|
|
------------
|
|
<a id="mp_rat_string_len"></a><pre>
|
|
mp_result <a href="imrat.h#L221">mp_rat_string_len</a>(mp_rat r, mp_size radix);
|
|
</pre>
|
|
- Reports the minimum number of characters required to represent `r` as a
|
|
zero-terminated string in the given `radix`.
|
|
Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
|
|
|
|
------------
|
|
<a id="mp_rat_decimal_len"></a><pre>
|
|
mp_result <a href="imrat.h#L226">mp_rat_decimal_len</a>(mp_rat r, mp_size radix, mp_size prec);
|
|
</pre>
|
|
- Reports the length in bytes of the buffer needed to convert `r` using the
|
|
`mp_rat_to_decimal()` function with the specified `radix` and `prec`. The
|
|
buffer size estimate may slightly exceed the actual required capacity.
|
|
|
|
------------
|
|
<a id="mp_rat_read_string"></a><pre>
|
|
mp_result <a href="imrat.h#L231">mp_rat_read_string</a>(mp_rat r, mp_size radix, const char *str);
|
|
</pre>
|
|
- Sets `r` to the value represented by a zero-terminated string `str` in the
|
|
format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded
|
|
denominator has value zero.
|
|
|
|
------------
|
|
<a id="mp_rat_read_cstring"></a><pre>
|
|
mp_result <a href="imrat.h#L238">mp_rat_read_cstring</a>(mp_rat r, mp_size radix, const char *str, char **end);
|
|
</pre>
|
|
- Sets `r` to the value represented by a zero-terminated string `str` in the
|
|
format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded
|
|
denominator has value zero. If `end` is not NULL then `*end` is set to
|
|
point to the first unconsumed character in the string, after parsing.
|
|
|
|
------------
|
|
<a id="mp_rat_read_ustring"></a><pre>
|
|
mp_result <a href="imrat.h#L252">mp_rat_read_ustring</a>(mp_rat r, mp_size radix, const char *str, char **end);
|
|
</pre>
|
|
- Sets `r` to the value represented by a zero-terminated string `str` having
|
|
one of the following formats, each with an optional leading sign flag:
|
|
|
|
```
|
|
n : integer format, e.g. "123"
|
|
n/d : ratio format, e.g., "-12/5"
|
|
z.ffff : decimal format, e.g., "1.627"
|
|
```
|
|
|
|
It returns `MP_UNDEF` if the effective denominator is zero. If `end` is not
|
|
NULL then `*end` is set to point to the first unconsumed character in the
|
|
string, after parsing.
|
|
|
|
------------
|
|
<a id="mp_rat_read_decimal"></a><pre>
|
|
mp_result <a href="imrat.h#L258">mp_rat_read_decimal</a>(mp_rat r, mp_size radix, const char *str);
|
|
</pre>
|
|
- Sets `r` to the value represented by a zero-terminated string `str` in the
|
|
format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the
|
|
effective denominator.
|
|
|
|
------------
|
|
<a id="mp_rat_read_cdecimal"></a><pre>
|
|
mp_result <a href="imrat.h#L264">mp_rat_read_cdecimal</a>(mp_rat r, mp_size radix, const char *str, char **end);
|
|
</pre>
|
|
- Sets `r` to the value represented by a zero-terminated string `str` in the
|
|
format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the
|
|
effective denominator. If `end` is not NULL then `*end` is set to point to
|
|
the first unconsumed character in the string, after parsing.
|
|
|
|
|
|
|
|
## Representation Details
|
|
|
|
> NOTE: You do not need to read this section to use IMath. This is provided
|
|
> for the benefit of developers wishing to extend or modify the internals of
|
|
> the library.
|
|
|
|
IMath uses a signed magnitude representation for arbitrary precision integers.
|
|
The magnitude is represented as an array of radix-R digits in increasing order
|
|
of significance; the value of R is chosen to be half the size of the largest
|
|
available unsigned integer type, so typically 16 or 32 bits. Digits are
|
|
represented as mp_digit, which must be an unsigned integral type.
|
|
|
|
Digit arrays are allocated using `malloc(3)` and `realloc(3)`. Because this
|
|
can be an expensive operation, the library takes pains to avoid allocation as
|
|
much as possible. For this reason, the `mpz_t` structure distinguishes between
|
|
how many digits are allocated and how many digits are actually consumed by the
|
|
representation. The fields of an `mpz_t` are:
|
|
|
|
mp_digit single; /* single-digit value (see note) */
|
|
mp_digit *digits; /* array of digits */
|
|
mp_size alloc; /* how many digits are allocated */
|
|
mp_size used; /* how many digits are in use */
|
|
mp_sign sign; /* the sign of the value */
|
|
|
|
The elements of `digits` at indices less than `used` are the significant
|
|
figures of the value; the elements at indices greater than or equal to `used`
|
|
are undefined (and may contain garbage). At all times, `used` must be at least
|
|
1 and at most `alloc`.
|
|
|
|
To avoid interaction with the memory allocator, single-digit values are stored
|
|
directly in the `mpz_t` structure, in the `single` field. The semantics of
|
|
access are the same as the more general case.
|
|
|
|
The number of digits allocated for an `mpz_t` is referred to in the library
|
|
documentation as its "precision". Operations that affect an `mpz_t` cause
|
|
precision to increase as needed. In any case, all allocations are measured in
|
|
digits, and rounded up to the nearest `mp_word` boundary. There is a default
|
|
minimum precision stored as a static constant default_precision (`imath.c`).
|
|
This value can be set using `mp_int_default_precision(n)`.
|
|
|
|
Note that the allocated size of an `mpz_t` can only grow; the library never
|
|
reallocates in order to decrease the size. A simple way to do so explicitly is
|
|
to use `mp_int_init_copy()`, as in:
|
|
|
|
```
|
|
mpz_t big, new;
|
|
|
|
/* ... */
|
|
mp_int_init_copy(&new, &big);
|
|
mp_int_swap(&new, &big);
|
|
mp_int_clear(&new);
|
|
```
|
|
|
|
The value of `sign` is 0 for positive values and zero, 1 for negative values.
|
|
Constants `MP_ZPOS` and `MP_NEG` are defined for these; no other sign values
|
|
are used.
|
|
|
|
If you are adding to this library, you should be careful to preserve the
|
|
convention that inputs and outputs can overlap, as described above. So, for
|
|
example, `mp_int_add(a, a, a)` is legal. Often, this means you must maintain
|
|
one or more temporary mpz_t structures for intermediate values. The private
|
|
macros `DECLARE_TEMP(N)`, `CLEANUP_TEMP()`, and `TEMP(K)` can be used to
|
|
maintain a conventional structure like this:
|
|
|
|
```c
|
|
{
|
|
/* Declare how many temp values you need.
|
|
Use TEMP(i) to access the ith value (0-indexed). */
|
|
DECLARE_TEMP(8);
|
|
...
|
|
|
|
/* Perform actions that must return MP_OK or fail. */
|
|
REQUIRE(mp_int_copy(x, TEMP(1)));
|
|
...
|
|
REQUIRE(mp_int_expt(TEMP(1), TEMP(2), TEMP(3)));
|
|
...
|
|
|
|
/* You can also use REQUIRE directly for more complex cases. */
|
|
if (some_difficult_question(TEMP(3)) != answer(x)) {
|
|
REQUIRE(MP_RANGE); /* falls through to cleanup (below) */
|
|
}
|
|
|
|
/* Ensure temporary values are cleaned up at exit.
|
|
|
|
If control reaches here via a REQUIRE failure, the code below
|
|
the cleanup will not be executed.
|
|
*/
|
|
CLEANUP_TEMP();
|
|
return MP_OK;
|
|
}
|
|
```
|
|
|
|
Under the covers, these macros are just maintaining an array of `mpz_t` values,
|
|
and a jump label to handle cleanup. You may only have one `DECLARE_TEMP` and
|
|
its corresponding `CLEANUP_TEMP` per function body.
|
|
|
|
"Small" integer values are represented by the types `mp_small` and `mp_usmall`,
|
|
which are mapped to appropriately-sized types on the host system. The default
|
|
for `mp_small` is "long" and the default for `mp_usmall` is "unsigned long".
|
|
You may change these, provided you insure that `mp_small` is signed and
|
|
`mp_usmall` is unsigned. You will also need to adjust the size macros:
|
|
|
|
MP_SMALL_MIN, MP_SMALL_MAX
|
|
MP_USMALL_MIN, MP_USMALL_MAX
|
|
|
|
... which are defined in `<imath.h>`, if you change these.
|
|
|
|
Rational numbers are represented using a pair of arbitrary precision integers,
|
|
with the convention that the sign of the numerator is the sign of the rational
|
|
value, and that the result of any rational operation is always represented in
|
|
lowest terms. The canonical representation for rational zero is 0/1. See
|
|
"imrat.h".
|
|
|
|
## Testing and Reporting of Bugs
|
|
|
|
Test vectors are included in the `tests/` subdirectory of the imath
|
|
distribution. When you run `make test`, it builds the `imtest` program and
|
|
runs all available test vectors. If any tests fail, you will get a line like
|
|
this:
|
|
|
|
x y FAILED v
|
|
|
|
Here, _x_ is the line number of the test which failed, _y_ is index of the test
|
|
within the file, and _v_ is the value(s) actually computed. The name of the
|
|
file is printed at the beginning of each test, so you can find out what test
|
|
vector failed by executing the following (with x, y, and v replaced by the
|
|
above values, and where "foo.t" is the name of the test file that was being
|
|
processed at the time):
|
|
|
|
% tail +x tests/foo.t | head -1
|
|
|
|
None of the tests should fail (but see [Note 2](#note2)); if any do, it
|
|
probably indicates a bug in the library (or at the very least, some assumption
|
|
I made which I shouldn't have). Please [file an
|
|
issue](https://github.com/creachadair/imath/issues/new), including the `FAILED`
|
|
test line(s), as well as the output of the above `tail` command (so I know what
|
|
inputs caused the failure).
|
|
|
|
If you build with the preprocessor symbol `DEBUG` defined as a positive
|
|
integer, the digit allocators (`s_alloc`, `s_realloc`) fill all new buffers
|
|
with the value `0xdeadbeefabad1dea`, or as much of it as will fit in a digit,
|
|
so that you can more easily catch uninitialized reads in the debugger.
|
|
|
|
## Notes
|
|
|
|
1. <a name="note1"></a>You can generally use the same variables for both input
|
|
and output. One exception is that you may not use the same variable for
|
|
both the quotient and the remainder of `mp_int_div()`.
|
|
|
|
2. <a name="note2"></a>Many of the tests for this library were written under
|
|
the assumption that the `mp_small` type is 32 bits or more. If you compile
|
|
with a smaller type, you may see `MP_RANGE` errors in some of the tests that
|
|
otherwise pass (due to conversion failures). Also, the pi generator (pi.c)
|
|
will not work correctly if `mp_small` is too short, as its algorithm for arc
|
|
tangent is fairly simple-minded.
|
|
|
|
## Contacts
|
|
|
|
The IMath library was written by Michael J. Fromberger.
|
|
|
|
If you discover any bugs or testing failures, please [open an
|
|
issue](https://github.com/creachadair/imath/issues/new). Please be sure to
|
|
include a complete description of what went wrong, and if possible, a test
|
|
vector for `imtest` and/or a minimal test program that will demonstrate the bug
|
|
on your system. Please also let me know what hardware, operating system, and
|
|
compiler you're using.
|
|
|
|
## Acknowledgements
|
|
|
|
The algorithms used in this library came from Vol. 2 of Donald Knuth's "The Art
|
|
of Computer Programming" (Seminumerical Algorithms). Thanks to Nelson Bolyard,
|
|
Bryan Olson, Tom St. Denis, Tushar Udeshi, and Eric Silva for excellent
|
|
feedback on earlier versions of this code. Special thanks to Jonathan Shapiro
|
|
for some very helpful design advice, as well as feedback and some clever ideas
|
|
for improving performance in some common use cases.
|
|
|
|
## License and Disclaimers
|
|
|
|
IMath is Copyright 2002-2009 Michael J. Fromberger
|
|
You may use it subject to the following Licensing Terms:
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
this software and associated documentation files (the "Software"), to deal in
|
|
the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
of the Software, and to permit persons to whom the Software is furnished to do
|
|
so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|