pub struct Real {
pub approx: Option<Approx>,
/* private fields */
}Expand description
The main structure representing a real number.
It contains a private field which determines the function and the arguments, and the current best approximation, if any.
The core idea here is that we represent a real number as a function
f(n: i32) -> BigInt, where n is the desired precision (typically
negative). The function is constructed such that |f(n)*2^n - x| < 2^n.
By using an increasingly negative n, we can approximate x to an
arbitrary precision.
§Warning on Undefined Behavior
The following things will cause undefined behavior, which may return an incorrect result, create an infinite loop, or panic:
- Division by zero
- Calling
Real::sqrton a negative number - Calling
Real::lnon a non-positive number - Calling
Real::tanon a number wherecosis zero - Calling
Real::asinorReal::acoson a number outside [-1, 1]
Fields§
§approx: Option<Approx>The current best approximation of the real number.
Implementations§
Source§impl Real
impl Real
Sourcepub fn appr(&mut self, precision: i32) -> Approx
pub fn appr(&mut self, precision: i32) -> Approx
Generates an approximation of the real number.
If we have already approximated the number with a sufficient precision, we simply scale the approximation. Otherwise we call the underlying approximate method.
§Examples
use computable_real::Real;
let mut n = Real::from(42);
assert_eq!(n.appr(0).value, 42.into()); // 42*2^0 = 42
assert_eq!(n.appr(-1).value, 84.into()); // 84*2^-1 = 42Sourcepub fn render_base(&self, n: u32, base: u32) -> String
pub fn render_base(&self, n: u32, base: u32) -> String
Renders the number in base with n digits to the right of
decimal point.
§Examples
use computable_real::Real;
let n = Real::from(42);
assert_eq!(n.render_base(0, 10), "42");
assert_eq!(n.render_base(2, 10), "42.00");
assert_eq!(n.render_base(4, 2), "101010.0000");
assert_eq!(n.render_base(0, 16), "2a");
let pi = Real::pi();
assert_eq!(pi.render_base(10, 10), "3.1415926536");
assert_eq!(pi.render_base(10, 16), "3.243f6a8886");
assert_eq!(pi.render_base(10, 2), "11.0010010001");Sourcepub fn render(&self, n: u32) -> String
pub fn render(&self, n: u32) -> String
Renders the number with n digits to the right of the decimal point.
Equivalent to render_base(n, 10).
§Examples
use computable_real::Real;
let n = Real::from(42);
assert_eq!(n.render(0), "42");
assert_eq!(n.render(2), "42.00");
let zero = Real::from(0);
assert_eq!(zero.render(0), "0");
assert_eq!(zero.render(2), "0.00");
let minus_one = Real::from(-1);
assert_eq!(minus_one.render(0), "-1");
assert_eq!(minus_one.render(2), "-1.00");Source§impl Real
Convenient methods and associated functions to create computable reals.
impl Real
Convenient methods and associated functions to create computable reals.
Sourcepub fn int(n: BigInt) -> Self
pub fn int(n: BigInt) -> Self
Creates a computable real representing an integer.
§Examples
use computable_real::Real;
let n = Real::int(42.into());
assert_eq!(n.render(0), "42");Sourcepub fn zero() -> Self
pub fn zero() -> Self
Creates a computable real representing zero.
Equivalent to Real::int(BigInt::ZERO).
Sourcepub fn one() -> Self
pub fn one() -> Self
Creates a computable real representing one.
Equivalent to Real::int(BigInt::one()).
Sourcepub fn pi() -> Self
pub fn pi() -> Self
Creates a computable real representing pi.
This uses John Machin’s formula from 1706:
pi/4 = 4 * atan(1/5) - atan(1/239)
§Examples
use computable_real::Real;
let pi = Real::pi();
assert_eq!(pi.render(10), "3.1415926536");Sourcepub fn squared(self) -> Self
pub fn squared(self) -> Self
Creates a computable real representing self^2.
§Examples
use computable_real::Real;
assert_eq!(Real::from(42).squared().render(0), "1764");
assert_eq!(Real::from(-42).squared().render(0), "1764");
assert_eq!(Real::from(1).squared().render(0), "1");Sourcepub fn select(self, a: Self, b: Self) -> Self
pub fn select(self, a: Self, b: Self) -> Self
Creates a computable real representing a if self < 0, and b
otherwise.
§Examples
use computable_real::Real;
let n = Real::from(42);
let m = Real::from(-42);
assert_eq!(n.clone().select(n.clone(), m.clone()).render(0), "-42");
assert_eq!(m.clone().select(n.clone(), m.clone()).render(0), "42");Sourcepub fn exp(self) -> Self
pub fn exp(self) -> Self
Creates a computable real representing exp(self).
§Examples
use computable_real::Real;
let n = Real::one();
let e = n.exp();
assert_eq!(e.render(10), "2.7182818285");Sourcepub fn cos(self) -> Self
pub fn cos(self) -> Self
Creates a computable real representing cos(self).
§Examples
use computable_real::Real;
let cos_pi = Real::pi().cos();
assert_eq!(cos_pi.render(0), "-1");
let cos_pi_half = Real::pi().shifted(-1).cos();
assert_eq!(cos_pi_half.render(0), "0");
let cos_n3_pi = (Real::pi() * Real::from(-3)).cos();
assert_eq!(cos_n3_pi.render(0), "-1");
let cos_pi_over_3 = (Real::pi() / Real::from(3)).cos();
assert_eq!(cos_pi_over_3.render(2), "0.50");Sourcepub fn sin(self) -> Self
pub fn sin(self) -> Self
Creates a computable real representing sin(self).
§Examples
use computable_real::{Real, Comparator};
use std::cmp::Ordering;
let sin_pi = Real::pi().sin();
assert_eq!(sin_pi.render(0), "0");
let sin_pi_half = Real::pi().shifted(-1).sin();
assert_eq!(sin_pi_half.render(0), "1");
let sin_n3_pi = (Real::pi() * Real::from(-3)).sin();
assert_eq!(sin_n3_pi.render(0), "0");
// sin(pi/3) = sqrt(3)/2
let cmp = Comparator::new().min_prec(-10);
let mut sin_pi_over_3 = (Real::pi() / Real::from(3)).sin();
let mut sqrt_3_over_2 = Real::from(3).sqrt() / Real::from(2);
assert_eq!(cmp.cmp(&mut sin_pi_over_3, &mut sqrt_3_over_2), Ordering::Equal);Sourcepub fn tan(self) -> Self
pub fn tan(self) -> Self
Creates a computable real representing tan(self).
§Examples
use computable_real::Real;
let tan_pi = Real::pi().tan();
assert_eq!(tan_pi.render(0), "0");
let tan_n3_pi = (Real::pi() * Real::from(-3)).tan();
assert_eq!(tan_n3_pi.render(0), "0");
let tan_pi_over_3 = (Real::pi() / Real::from(3)).tan();
assert_eq!(tan_pi_over_3.render(0), "2");Sourcepub fn asin(self) -> Self
pub fn asin(self) -> Self
Creates a computable real representing asin(self).
§Examples
use computable_real::{Real, Comparator};
use std::cmp::Ordering;
let asin_zero = Real::from(0).asin();
assert_eq!(asin_zero.render(0), "0");
let cmp = Comparator::new().min_prec(-10);
let mut asin_one = Real::from(1).asin();
let mut half_pi = Real::pi().shifted(-1);
assert_eq!(cmp.cmp(&mut asin_one, &mut half_pi), Ordering::Equal);
let n_one_sqrt_2 = Real::from(-1) / Real::from(2).sqrt();
let mut val = n_one_sqrt_2.asin();
let mut n_pi_over_4 = -Real::pi().shifted(-2);
assert_eq!(cmp.cmp(&mut val, &mut n_pi_over_4), Ordering::Equal);Sourcepub fn acos(self) -> Self
pub fn acos(self) -> Self
Creates a computable real representing acos(self).
§Examples
use computable_real::{Real, Comparator};
use std::cmp::Ordering;
let cmp = Comparator::new().min_prec(-10);
let mut acos_zero = Real::from(0).acos();
let mut half_pi = Real::pi().shifted(-1);
assert_eq!(cmp.cmp(&mut acos_zero, &mut half_pi), Ordering::Equal);
let mut acos_one = Real::from(1).acos();
assert_eq!(cmp.cmp(&mut acos_one, &mut Real::from(0)), Ordering::Equal);
let mut acos_half = Real::from(1).shifted(-1).acos();
let mut pi_over_3 = Real::pi() / Real::from(3);
assert_eq!(cmp.cmp(&mut acos_half, &mut pi_over_3), Ordering::Equal);Sourcepub fn atan(self) -> Self
pub fn atan(self) -> Self
Creates a computable real representing atan(self).
§Examples
use computable_real::{Real, Comparator};
use std::cmp::Ordering;
let atan_zero = Real::from(0).atan();
assert_eq!(atan_zero.render(0), "0");
let cmp = Comparator::new().min_prec(-10);
let mut atan_one = Real::from(1).atan();
let mut pi_over_4 = Real::pi().shifted(-2);
assert_eq!(cmp.cmp(&mut atan_one, &mut pi_over_4), Ordering::Equal);
let n_one_sqrt_3 = Real::from(-1) / Real::from(3).sqrt();
let mut val = n_one_sqrt_3.atan();
let mut n_pi_over_6 = -Real::pi() / Real::from(6);
assert_eq!(cmp.cmp(&mut val, &mut n_pi_over_6), Ordering::Equal);Sourcepub fn ln(self) -> Self
pub fn ln(self) -> Self
Creates a computable real representing ln(self), the natural logarithm.
§Examples
use computable_real::Real;
let ln1 = Real::from(1).ln();
assert_eq!(ln1.render(0), "0");
let e = Real::from(1).exp();
let ln_e = e.ln();
assert_eq!(ln_e.render(0), "1");Sourcepub fn sqrt(self) -> Self
pub fn sqrt(self) -> Self
Creates a computable real representing sqrt(self).
§Examples
use computable_real::Real;
let sqrt_2 = Real::from(2).sqrt();
assert_eq!(sqrt_2.render(10), "1.4142135624");
let sqrt_1 = Real::from(1).sqrt();
assert_eq!(sqrt_1.render(0), "1");
let sqrt_0 = Real::from(0).sqrt();
assert_eq!(sqrt_0.render(0), "0");
let sqrt_quarter = Real::from(1).shifted(-2).sqrt();
assert_eq!(sqrt_quarter.render(3), "0.500");Sourcepub fn shifted(self, n: i32) -> Self
pub fn shifted(self, n: i32) -> Self
Creates a computable real representing self * 2^n.
§Examples
use computable_real::Real;
assert_eq!(Real::from(42).shifted(0).render(0), "42");
assert_eq!(Real::from(42).shifted(2).render(0), "168");
assert_eq!(Real::from(42).shifted(-2).render(3), "10.500");
assert_eq!(Real::from(42).shifted(-2).shifted(2).render(0), "42");Sourcepub fn inv(self) -> Self
pub fn inv(self) -> Self
Creates a computable real representing 1/self.
§Examples
use computable_real::Real;
assert_eq!(Real::from(42).inv().render(10), "0.0238095238");
assert_eq!(Real::from(1).inv().render(0), "1");
assert_eq!(Real::from(-1).inv().render(0), "-1");
assert_eq!(Real::from(42).inv().inv().render(0), "42");Trait Implementations§
Source§impl Add for Real
impl Add for Real
Source§fn add(self, rhs: Self) -> Self
fn add(self, rhs: Self) -> Self
Adds two real numbers by consuming them and returning a new real number.
§Examples
use computable_real::Real;
assert_eq!((Real::from(1) + Real::from(2)).render(0), "3");
assert_eq!((Real::from(1) + Real::from(-1)).render(0), "0");
assert_eq!((Real::pi() + Real::from(1).exp()).render(5), "5.85987");Source§impl Div for Real
impl Div for Real
Source§fn div(self, rhs: Self) -> Self
fn div(self, rhs: Self) -> Self
Divides two real numbers by consuming them and returning a new real number.
§Examples
use computable_real::Real;
assert_eq!((Real::from(1) / Real::from(2)).render(5), "0.50000");
assert_eq!((Real::from(1) / Real::from(-1)).render(5), "-1.00000");
assert_eq!((Real::pi() / Real::from(1).exp()).render(5), "1.15573");Source§impl From<Ratio<BigInt>> for Real
impl From<Ratio<BigInt>> for Real
Source§fn from(value: BigRational) -> Self
fn from(value: BigRational) -> Self
Converts a BigRational into a real number.
§Examples
use computable_real::Real;
use num::{BigInt, BigRational};
let a = BigRational::new(BigInt::from(1), BigInt::from(2));
assert_eq!(Real::from(a).render(5), "0.50000");
let b = BigRational::new(BigInt::from(-1), BigInt::from(3));
assert_eq!(Real::from(b).render(5), "-0.33333");Source§impl From<Real> for BigInt
impl From<Real> for BigInt
Source§fn from(value: Real) -> BigInt
fn from(value: Real) -> BigInt
Converts a real number into a BigInt.
It is guaranteed that the difference is less than 1.
§Examples
use computable_real::Real;
use num::BigInt;
let a = Real::from(-42);
assert_eq!(BigInt::from(a).to_string(), "-42");
let b = Real::from(0.999);
assert!(BigInt::from(b) <= 1.into());Source§impl From<f64> for Real
impl From<f64> for Real
Source§fn from(value: f64) -> Self
fn from(value: f64) -> Self
Converts an f64 into a real number.
Note that due to the inherent imprecision of floating point numbers, the conversion may not be exact.
§Examples
use computable_real::Real;
let r: Real = 3.14.into();
assert_eq!(r.render(2), "3.14");
assert_eq!(r.render(20), "3.14000000000000012434");
let s: Real = (-0.0003).into();
assert_eq!(s.render(5), "-0.00030");Source§impl FromStr for Real
impl FromStr for Real
Source§fn from_str(str: &str) -> Result<Self, Self::Err>
fn from_str(str: &str) -> Result<Self, Self::Err>
Parses a decimal string into a real number.
§Examples
use computable_real::Real;
use std::str::FromStr;
let a: Real = "3.14".parse().unwrap();
assert_eq!(a.render(2), "3.14");
let b: Real = "-0.0000000000000000042".parse().unwrap();
assert_eq!(b.render(20), "-0.00000000000000000420");
let c: Real = "42".parse().unwrap();
assert_eq!(c.render(0), "42");Source§type Err = ParseBigIntError
type Err = ParseBigIntError
Source§impl Mul for Real
impl Mul for Real
Source§fn mul(self, rhs: Self) -> Self
fn mul(self, rhs: Self) -> Self
Multiplies two real numbers by consuming them and returning a new real number.
§Examples
use computable_real::Real;
assert_eq!((Real::from(1) * Real::from(2)).render(0), "2");
assert_eq!((Real::from(1) * Real::from(-1)).render(0), "-1");
assert_eq!((Real::pi() * Real::from(-1)).render(5), "-3.14159");
assert_eq!((Real::pi() * Real::from(0)).render(5), "0.00000");Source§impl Sub for Real
impl Sub for Real
Source§fn sub(self, rhs: Self) -> Self
fn sub(self, rhs: Self) -> Self
Subtracts two real numbers by consuming them and returning a new real number.
§Examples
use computable_real::Real;
assert_eq!((Real::from(1) - Real::from(2)).render(0), "-1");
assert_eq!((Real::from(1) - Real::from(-1)).render(0), "2");
assert_eq!((Real::from(1) - Real::from(1)).render(0), "0");
assert_eq!((Real::pi() - Real::from(1).exp()).render(5), "0.42331");