dec/
lib.rs

1// Copyright Materialize, Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! dec is a decimal arithmetic library for Rust.
17//!
18//! # Introduction
19//!
20//! From the [Decimal Arithmetic FAQ][faq]:
21//!
22//! > Most people in the world use decimal (base 10) arithmetic. When large or
23//! > small values are needed, exponents which are powers of ten are used.
24//! > However, most computers have only binary (base two) arithmetic, and when
25//! > exponents are used (in floating-poing numbers) they are powers of two.
26//! >
27//! > Binary floating-point numbers can only approximate common decimal numbers.
28//! > The value 0.1, for example, would need an infinitely recurring binary
29//! > fraction. In contrast, a decimal number system can represent 0.1 exactly,
30//! > as one tenth (that is, 10<sup>-1</sup>). Consequently, binary
31//! > floating-point cannot be used for financial calculations, or indeed for
32//! > any calculations where the results achieved are required to match those
33//! > which might be calculated by hand.
34//!
35//! dec is an implementation of the General Decimal Arithmetic standard, which
36//! precisely describes both a limited-precision floating-point decimal
37//! arithmetic and an arbitrary precision floating-point decimal arithmetic.
38//!
39//! The latest draft of the standard is available online at
40//! <http://speleotrove.com/decimal/decarith.html>. The floating-point
41//! arithmetic additionally conforms to the IEEE 754-2008 specification, but
42//! this specification is not freely available.
43//!
44//! # Details
45//!
46//! dec is a safe Rust API atop the C reference implementation, [libdecnumber].
47//! Unsafe C bindings to libdecnumber are available in the [decnumber-sys]
48//! crate.
49//!
50//! The main types exposed by this library are as follows:
51//!
52//!  * [`Decimal32`], a 32-bit decimal floating-point representation which
53//!    provides 7 decimal digits of precision in a compressed format. This type
54//!    is intended for storage and interchange only and so does not support any
55//!    arithmetic functions.
56//!
57//!  * [`Decimal64`], a 64-bit decimal floating-point representation which
58//!    provides 16 decimal digits of precision in a compressed format along with
59//!    various arithmetic functions.
60//!
61//!  * [`Decimal128`], a 128-bit decimal floating-point representation which
62//!    provides 34 decimal digits of precision in a compressed format along with
63//!    various arithmetic functions.
64//!
65//!  * [`Decimal`], a decimal representation whose precision is configurable via
66//!    its generic `N` parameter.
67//!
68//!  * [`Context`], which hosts most of the actual functions on the above types.
69//!    A context configures the behavior of the various operations (e.g.,
70//!    rounding mode) and accumulates exceptional conditions (e.g., overflow).
71//!
72//! # Examples
73//!
74//! The following example demonstrates the basic usage of the library:
75//!
76//! ```
77//! # use std::error::Error;
78//! use dec::Decimal128;
79//!
80//! let x: Decimal128 = ".1".parse()?;
81//! let y: Decimal128 = ".2".parse()?;
82//! let z: Decimal128 = ".3".parse()?;
83//!
84//! assert_eq!(x + y, z);
85//! assert_eq!((x + y + z).to_string(), "0.6");
86//!
87//! # Ok::<_, Box<dyn Error>>(())
88//! ```
89//!
90//! [faq]: http://speleotrove.com/decimal/decifaq.html
91//! [libdecnumber]: http://speleotrove.com/decimal/decarith.html
92//! [decnumber-sys]: https://docs.rs/decnumber-sys
93
94#![deny(missing_debug_implementations, missing_docs)]
95#![cfg_attr(docsrs, feature(doc_cfg))]
96
97mod context;
98#[macro_use]
99mod conv;
100mod decimal;
101mod decimal128;
102mod decimal32;
103mod decimal64;
104mod error;
105mod ordered;
106#[cfg(tests)]
107mod tests;
108
109pub use context::{Class, Context, Rounding, Status};
110#[cfg(feature = "serde")]
111pub use decimal::serde_decimal_from_non_float_primitives;
112pub use decimal::Decimal;
113pub use decimal128::Decimal128;
114pub use decimal32::Decimal32;
115pub use decimal64::Decimal64;
116pub use error::{
117    InvalidExponentError, InvalidPrecisionError, ParseDecimalError, TryFromDecimalError,
118};
119pub use ordered::OrderedDecimal;