pub enum TowerValue {
Integer(RnsInt),
Rational(RnsRational),
Algebraic(AlgebraicNumber),
Computable(ComputableReal),
Symbolic(SymbolicExpr),
}Expand description
A value somewhere in the number tower.
Variants§
Integer(RnsInt)
Rational(RnsRational)
Algebraic(AlgebraicNumber)
Computable(ComputableReal)
Symbolic(SymbolicExpr)
Implementations§
Source§impl TowerValue
impl TowerValue
Sourcepub fn level(&self) -> TowerLevel
pub fn level(&self) -> TowerLevel
The level this value currently sits at.
Sourcepub fn channels(&self) -> Channels
pub fn channels(&self) -> Channels
Best-effort channels for this value (symbolic falls back to the standard set).
Sourcepub fn reduce(&self) -> TowerValue
pub fn reduce(&self) -> TowerValue
Reduce to the lowest valid level (applied to a fixed point).
Sourcepub fn elevate_to(&self, target: TowerLevel) -> TowerValue
pub fn elevate_to(&self, target: TowerLevel) -> TowerValue
Elevate to at least target (for mixed-level operations). Symbolic is the
top; numeric levels rise one step at a time.
Sourcepub fn to_f64(&self) -> Option<f64>
pub fn to_f64(&self) -> Option<f64>
Decimal approximation (levels 0–3; symbolic is simplified/evaluated first).
Examples found in repository?
examples/float_comparison.rs (line 44)
22fn main() {
23 let ch = Channels::standard(32);
24 println!("== adele-ring :: exact vs f64 ==\n");
25 println!(
26 "{:<16} | {:<10} | {:<22} | {:<12} | ULPs",
27 "expression", "exact", "f64 result", "abs error"
28 );
29 println!("{}", "-".repeat(78));
30
31 // 0.1 + 0.2 = 3/10
32 let exact = RnsRational::from_fraction(1, 10, ch.clone())
33 .add(&RnsRational::from_fraction(1, 5, ch.clone()));
34 row("0.1 + 0.2", &exact.display(), 0.1 + 0.2, exact.to_f64());
35
36 // 1/3 * 3 = 1
37 let one = RnsRational::from_fraction(1, 3, ch.clone()).mul(&RnsRational::from_int(3, ch.clone()));
38 row("1/3 * 3", &one.display(), (1.0 / 3.0) * 3.0, one.to_f64());
39
40 // sqrt(2) * sqrt(2) = 2 (drops to Integer through the tower)
41 let s2 = TowerValue::Algebraic(AlgebraicNumber::sqrt(2, ch.clone()));
42 let two = s2.mul(&s2);
43 let naive = 2f64.sqrt() * 2f64.sqrt();
44 row("sqrt2 * sqrt2", "2", naive, two.to_f64().unwrap());
45
46 // sin(pi) = 0 (exact identity; f64 gives ~1.2e-16)
47 let sin_pi = TowerValue::Symbolic(SymbolicExpr::Pi).sin();
48 row("sin(pi)", "0", std::f64::consts::PI.sin(), sin_pi.to_f64().unwrap());
49
50 // 1/7 * 7 = 1
51 let one7 = RnsRational::from_fraction(1, 7, ch.clone()).mul(&RnsRational::from_int(7, ch));
52 row("1/7 * 7", &one7.display(), (1.0 / 7.0) * 7.0, one7.to_f64());
53
54 println!("\nEvery `exact` column is bit-for-bit correct; the f64 column drifts.");
55}Sourcepub fn digits(&self, precision: u64) -> RnsRational
pub fn digits(&self, precision: u64) -> RnsRational
Produce exact digits to precision decimal places, as a rational.
Sourcepub fn add(&self, other: &TowerValue) -> TowerValue
pub fn add(&self, other: &TowerValue) -> TowerValue
Addition, dropping the result to its lowest valid level.
Sourcepub fn mul(&self, other: &TowerValue) -> TowerValue
pub fn mul(&self, other: &TowerValue) -> TowerValue
Multiplication, dropping the result to its lowest valid level.
Examples found in repository?
examples/float_comparison.rs (line 42)
22fn main() {
23 let ch = Channels::standard(32);
24 println!("== adele-ring :: exact vs f64 ==\n");
25 println!(
26 "{:<16} | {:<10} | {:<22} | {:<12} | ULPs",
27 "expression", "exact", "f64 result", "abs error"
28 );
29 println!("{}", "-".repeat(78));
30
31 // 0.1 + 0.2 = 3/10
32 let exact = RnsRational::from_fraction(1, 10, ch.clone())
33 .add(&RnsRational::from_fraction(1, 5, ch.clone()));
34 row("0.1 + 0.2", &exact.display(), 0.1 + 0.2, exact.to_f64());
35
36 // 1/3 * 3 = 1
37 let one = RnsRational::from_fraction(1, 3, ch.clone()).mul(&RnsRational::from_int(3, ch.clone()));
38 row("1/3 * 3", &one.display(), (1.0 / 3.0) * 3.0, one.to_f64());
39
40 // sqrt(2) * sqrt(2) = 2 (drops to Integer through the tower)
41 let s2 = TowerValue::Algebraic(AlgebraicNumber::sqrt(2, ch.clone()));
42 let two = s2.mul(&s2);
43 let naive = 2f64.sqrt() * 2f64.sqrt();
44 row("sqrt2 * sqrt2", "2", naive, two.to_f64().unwrap());
45
46 // sin(pi) = 0 (exact identity; f64 gives ~1.2e-16)
47 let sin_pi = TowerValue::Symbolic(SymbolicExpr::Pi).sin();
48 row("sin(pi)", "0", std::f64::consts::PI.sin(), sin_pi.to_f64().unwrap());
49
50 // 1/7 * 7 = 1
51 let one7 = RnsRational::from_fraction(1, 7, ch.clone()).mul(&RnsRational::from_int(7, ch));
52 row("1/7 * 7", &one7.display(), (1.0 / 7.0) * 7.0, one7.to_f64());
53
54 println!("\nEvery `exact` column is bit-for-bit correct; the f64 column drifts.");
55}Sourcepub fn sqrt(&self) -> TowerValue
pub fn sqrt(&self) -> TowerValue
Square root: a perfect square drops to Integer, otherwise rises to
Algebraic.
Sourcepub fn sin(&self) -> TowerValue
pub fn sin(&self) -> TowerValue
sin: checks the symbolic identity graph; otherwise stays symbolic.
Examples found in repository?
examples/float_comparison.rs (line 47)
22fn main() {
23 let ch = Channels::standard(32);
24 println!("== adele-ring :: exact vs f64 ==\n");
25 println!(
26 "{:<16} | {:<10} | {:<22} | {:<12} | ULPs",
27 "expression", "exact", "f64 result", "abs error"
28 );
29 println!("{}", "-".repeat(78));
30
31 // 0.1 + 0.2 = 3/10
32 let exact = RnsRational::from_fraction(1, 10, ch.clone())
33 .add(&RnsRational::from_fraction(1, 5, ch.clone()));
34 row("0.1 + 0.2", &exact.display(), 0.1 + 0.2, exact.to_f64());
35
36 // 1/3 * 3 = 1
37 let one = RnsRational::from_fraction(1, 3, ch.clone()).mul(&RnsRational::from_int(3, ch.clone()));
38 row("1/3 * 3", &one.display(), (1.0 / 3.0) * 3.0, one.to_f64());
39
40 // sqrt(2) * sqrt(2) = 2 (drops to Integer through the tower)
41 let s2 = TowerValue::Algebraic(AlgebraicNumber::sqrt(2, ch.clone()));
42 let two = s2.mul(&s2);
43 let naive = 2f64.sqrt() * 2f64.sqrt();
44 row("sqrt2 * sqrt2", "2", naive, two.to_f64().unwrap());
45
46 // sin(pi) = 0 (exact identity; f64 gives ~1.2e-16)
47 let sin_pi = TowerValue::Symbolic(SymbolicExpr::Pi).sin();
48 row("sin(pi)", "0", std::f64::consts::PI.sin(), sin_pi.to_f64().unwrap());
49
50 // 1/7 * 7 = 1
51 let one7 = RnsRational::from_fraction(1, 7, ch.clone()).mul(&RnsRational::from_int(7, ch));
52 row("1/7 * 7", &one7.display(), (1.0 / 7.0) * 7.0, one7.to_f64());
53
54 println!("\nEvery `exact` column is bit-for-bit correct; the f64 column drifts.");
55}Trait Implementations§
Source§impl Clone for TowerValue
impl Clone for TowerValue
Source§fn clone(&self) -> TowerValue
fn clone(&self) -> TowerValue
Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for TowerValue
impl !UnwindSafe for TowerValue
impl Freeze for TowerValue
impl Send for TowerValue
impl Sync for TowerValue
impl Unpin for TowerValue
impl UnsafeUnpin for TowerValue
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more