1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//!
//! ARPFloat is an implementation of arbitrary precision
//! [floating point](https://en.wikipedia.org/wiki/IEEE_754) data
//! structures and utilities. The library can be used to emulate existing
//! floating point types, such as FP16, FP32 or FP128, and create new
//! floating-point types that scale to hundreds of digits, and perform very
//! accurate calculations. The library contains mathematical functions such as
//! `log`, `exp`, `sin`, `cos`, `tan`, and constants such as `pi` and `e`
//!
//! In ARPFloat the rounding mode is a part of the type-system, and this solves
//! a number of problem that show up when using the global rounding flag that's
//! defined in `fenv.h`.
//!
//! ##no_std
//! The library can be built without the standard library.
//!
//!### Example
//!```
//! use arpfloat::Float;
//! use arpfloat::FP128;
//!
//! // Create the number '5' in FP128 format.
//! let n = Float::from_f64(5.).cast(FP128);
//!
//! // Use Newton-Raphson to find the square root of 5.
//! let mut x = n.clone();
//! for _ in 0..20 {
//! x += (&n / &x)/2;
//! }
//!
//! println!("fp128: {}", x);
//! println!("fp64: {}", x.as_f64());
//! ```
//!
//!The program above will print this output:
//!```console
//!fp128: 2.2360679774997896964091736687312763
//!fp64: 2.23606797749979
//!```
//!
//!The library also provides API that exposes rounding modes, and low-level
//!operations.
//!
//!```
//! use arpfloat::FP128;
//! use arpfloat::RoundingMode::NearestTiesToEven;
//! use arpfloat::Float;
//!
//! let x = Float::from_u64(FP128, 1<<53);
//! let y = Float::from_f64(1000.0).cast(FP128);
//!
//! let val = Float::mul_with_rm(&x, &y, NearestTiesToEven);
//! ```
//!
//! View the internal representation of floating point numbers:
//! ```
//! use arpfloat::Float;
//! use arpfloat::FP16;
//!
//! let fp = Float::from_i64(FP16, 15);
//!
//! fp.dump(); // Prints FP[+ E=+3 M=11110000000]
//!
//! let m = fp.get_mantissa();
//! m.dump(); // Prints 11110000000
//!```
//!
//! Control the rounding mode for type conversion:
//!```
//! use arpfloat::{FP16, FP32, RoundingMode, Float};
//!
//! let x = Float::from_u64(FP32, 2649); // Load an FP32 Value.
//! let b = x.cast_with_rm(FP16, RoundingMode::Zero); // Convert to FP16.
//! println!("{}", b); // Prints 2648!
//!```
//!
//! Define new float formats and use high-precision transcendental functions:
//!```
//! use arpfloat::{Float, Semantics, RoundingMode};
//! // Define a new float format with 120 bits of accuracy, and dynamic range
//! // of 2^10.
//! let sem = Semantics::new(10, 120, RoundingMode::NearestTiesToEven);
//!
//! let pi = Float::pi(sem);
//! let x = Float::exp(&pi);
//! println!("e^pi = {}", x); // Prints 23.1406926327792....
//!```
//!
//! Floating point numbers can be converted to
//! [Continued Fractions](https://en.wikipedia.org/wiki/Continued_fraction) that
//! approximate the value.
//!
//! ```rust
//! use arpfloat::{Float, FP256, RoundingMode};
//!
//! let ln = Float::ln2(FP256);
//! println!("ln(2) = {}", ln);
//! for i in 1..20 {
//! let (p,q) = ln.as_fraction(i);
//! println!("{}/{}", p.as_decimal(), q.as_decimal());
//! }
//! ```
//!The program above will print this output:
//!```console
//! ln(2) = .6931471805599453094172321214581765680755001343.....
//! 0/1
//! 1/1
//! 2/3
//! 7/10
//! 9/13
//! 61/88
//! 192/277
//! 253/365
//! 445/642
//! 1143/1649
//! 1588/2291
//! 2731/3940
//! ....
//!```
extern crate std;
pub use BigInt;
pub use Float;
pub use RoundingMode;
pub use Semantics;
pub use ;
// Conditionally include a module based on feature flag