computable_real/
lib.rs

1//! This crate provides an API to work with computable real numbers (or recursive
2//! real numbers). We represent real numbers as a function that accepts a
3//! desired precision level and returns an approximation of the real number.
4//! By providing an increasingly smaller precision level, we can approximate
5//! the real number to an arbitrary precision.
6//!
7//! The idea is from the paper [Towards an API for the Real Numbers] by H. Boehm,
8//! and the overall design and a lot of the functions are from the [CR.java] and
9//! [UnaryCRFunction.java] files in the Android ART repository.
10//!
11//! # Example
12//!
13//! ```
14//! use computable_real::Real;
15//!
16//! let pi = Real::pi();
17//! println!("π = {}", pi.render(10));
18//! assert_eq!(pi.render(10), "3.1415926536");
19//! let sin_pi = pi.clone().sin();
20//! println!("sin(π) = {}", sin_pi.render(10));
21//! assert_eq!(sin_pi.render(10), "0.0000000000");
22//!
23//! // We can evaluate and render pi past the limit of f64
24//! println!("π = {}", pi.render(30));
25//! assert_eq!(pi.render(30), "3.141592653589793238462643383280");
26//! ```
27//!
28//! [CR.java]: https://android-review.googlesource.com/c/platform/art/+/1012109/7/test/1972-math-prec/src/com/hp/creals/CR.java
29//! [UnaryCRFunction.java]: https://android-review.googlesource.com/c/platform/art/+/1012109/7/test/1972-math-prec/src/com/hp/creals/UnaryCRFunction.java
30//! [Towards an API for the Real Numbers]: https://dl.acm.org/doi/pdf/10.1145/3385412.3386037
31
32mod real;
33pub use real::Comparator;
34pub use real::Real;
35
36mod approx;
37pub use approx::Approx;
38
39mod prim;
40use prim::Primitive;
41
42mod traits;
43
44use num::BigInt;
45
46fn bound_log2(n: i32) -> i32 {
47    ((n.abs() + 1) as f64).log2().ceil() as i32
48}
49
50fn scale(n: BigInt, bits: i32) -> BigInt {
51    fn shift(n: BigInt, bits: i32) -> BigInt {
52        if bits >= 0 {
53            n << bits
54        } else {
55            n >> -bits
56        }
57    }
58
59    if bits >= 0 {
60        n << bits
61    } else {
62        (shift(n, bits + 1) + BigInt::from(1)) >> 1
63    }
64}