Skip to content

Commit

Permalink
Add module documentation
Browse files Browse the repository at this point in the history
The `ll` module is rather opaque to others, so add in some documentation
containing general overview and imporant details.
  • Loading branch information
Aatch committed Sep 29, 2015
1 parent 2a0bf55 commit 426f38e
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/ll/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
* Base conversion utilities
*
* Provides functions for converting an integer to/from a given base. In both `to_base` and
* `from_base` the base-N output or input (respectively) is stored as raw bytes. That means that a
* base-10 input contains bytes each with a value from 0-9.
*/

use std::intrinsics::assume;

use ll;
Expand Down
65 changes: 65 additions & 0 deletions src/ll/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,71 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/*!
* This module provides the low-level operations for working with arbitrary precision numbers.
*
* ## Overview
*
* This module forms the core of the library. As such, the functions are required to be highly
* performant, even small inefficiencies can cause a large impact given how frequently some of
* these functions are called. `addmul` for example is one of the most frequently called functions
* in the library, so an efficiencies there will be multiplied out to almost the entire library.
*
* There are no real restrictions on the functions that can implemented in here. Exposed functions
* should be generally useful to high-level code, but otherwise any operation that can be more
* efficiently implemented here and then exposed by a higher-level API is a candidate.
*
* The functions in this module assume that all inputs are valid, though some checking is performed
* in debug builds.
*
* ## Limbs
*
* A `Limb` is a single "digit" in an arbitrary-precision integer. To explain, consider the
* standard base we work in, base-10. Base-10 uses represents numbers as a sequence of the digits
* 0-9. The number 251 is 2 x 10^2 + 5 x 10^1 + 1 x 10^0. Similarly base-16 (hexadecimal) uses
* sixteen digits and a base of 16 to represent numbers.
*
* A `Limb` is one word, with N bits (32 on a 32-bit platform, 64 on a 64-bit platform), so it can
* represent 2^N unique values. It can therefore form the basis of a base-2^N number system. The
* word "Limb" is used by GMP to distinguish it from a regular numerical digit, and there is no
* obvious reason to use different terminology.
*
* `Limb` itself implements a number of useful methods. The basic mathematical operators are
* implemented to provide wrapping behaviour by default. The most basic operations are also
* implemented on `Limb`, notably multiplication with a two-word output and division of a two-word
* numerator by a one-word denominator. The implementations of these operations are done with
* inline assembly on x86 platforms with a Rust implementation as fallback.
*
* ## Integer representation
*
* Integers are passed around as pointers to a series of `Limb`s. The limbs are stored
* least-significant first. If required, a size parameter is also provided, but otherwise is
* omitted when it can be inferred from other sources of information. This is the case with the
* output pointers used to store the result, they are assumed to have enough memory store the
* result as the maximum output size is bounded by the size of the inputs.
*
* The integers are not required to be "normalized" in most cases. That is, they may have
* zero-value limbs in the highest positions. Functions should aim to avoid requiring normalized
* integers but otherwise explicitly document said requirement.
*
* ## Memory allocation
*
* No function will allocate memory for a return value. However, it is sometimes required to
* allocate "scratch space" for storing intermediate values. This scratch space is always temporary
* and freed before the function returns. Functions that need to make heavy use of scratch space
* while also being recursive, are split so that scratch space can be re-used.
*
* ## Argument Conventions
*
* There are no hard-and-fast rules for the argument conventions in this module. There are however
* some general conventions:
*
* * Output/Result pointer goes first (if applicable).
* * Pointer and matching size are kept close together in the argument list.
* * Sizes come after the matching pointers. For example, `add_n` takes two pointers and a length,
* the length applies to both pointers and so comes after both of them.
*/

use std::intrinsics::abort;
use std::cmp::Ordering;

Expand Down

0 comments on commit 426f38e

Please sign in to comment.