Struct Real

Source
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

Comparing two computable real numbers is inefficient, and indecidable in general. Because of this, we do not validate whether the arguments to the functions are valid. It is the user's responsibility to ensure that the arguments are in the function domain. Anything else will cause undefined behavior.

The following things will cause undefined behavior, which may return an incorrect result, create an infinite loop, or panic:

Fields§

§approx: Option<Approx>

The current best approximation of the real number.

Implementations§

Source§

impl Real

Source

pub fn new(prim: Primitive) -> Self

Creates a new real number from a primitive.

Normally you would not use this directly, but rather use one of the other associated functions like Real::int or Real::pi.

Source

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 = 42
Source

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");
Source

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.

Source

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");
Source

pub fn zero() -> Self

Creates a computable real representing zero.

Equivalent to Real::int(BigInt::ZERO).

Source

pub fn one() -> Self

Creates a computable real representing one.

Equivalent to Real::int(BigInt::one()).

Source

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");
Source

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");
Source

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");
Source

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");
Source

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");
Source

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);
Source

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");
Source

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);
Source

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);
Source

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);
Source

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");
Source

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");
Source

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");
Source

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

Source§

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§

type Output = Real

The resulting type after applying the + operator.
Source§

impl Clone for Real

Source§

fn clone(&self) -> Real

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Real

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Div for Real

Source§

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§

type Output = Real

The resulting type after applying the / operator.
Source§

impl From<BigInt> for Real

Source§

fn from(value: BigInt) -> Self

Converts a BigInt into a real number.

§Examples
use computable_real::Real;
use num::BigInt;

let n: BigInt = "-123456789012345678901234567890".parse().unwrap();
let r: Real = n.into();
assert_eq!(r.render(0), "-123456789012345678901234567890");
Source§

impl From<Ratio<BigInt>> for Real

Source§

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

Source§

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<Real> for f64

Source§

fn from(value: Real) -> f64

Converts a real number into an f64.

§Examples
use computable_real::Real;

let pi = Real::pi();
let f: f64 = pi.into();
assert_eq!(f, std::f64::consts::PI);
Source§

impl From<f64> for Real

Source§

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 From<i32> for Real

Source§

fn from(value: i32) -> Self

Converts an i32 into a real number.

Equivalent to Real::int(BigInt::from(value)).

Source§

impl FromStr for Real

Source§

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

The associated error which can be returned from parsing.
Source§

impl Mul for Real

Source§

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§

type Output = Real

The resulting type after applying the * operator.
Source§

impl Neg for Real

Source§

fn neg(self) -> Self

Negates a real number by consuming it and returning a new real number.

Source§

type Output = Real

The resulting type after applying the - operator.
Source§

impl Sub for Real

Source§

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");
Source§

type Output = Real

The resulting type after applying the - operator.

Auto Trait Implementations§

§

impl Freeze for Real

§

impl RefUnwindSafe for Real

§

impl Send for Real

§

impl Sync for Real

§

impl Unpin for Real

§

impl UnwindSafe for Real

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.