use num_bigint::{BigInt, BigUint};
use crate::binary::{Binary, UBinary, UXBinary, XBinary};
pub fn bin(mantissa: i64, exponent: i64) -> Binary {
Binary::new(BigInt::from(mantissa), BigInt::from(exponent))
}
pub fn ubin(mantissa: u64, exponent: i64) -> UBinary {
UBinary::new(BigUint::from(mantissa), BigInt::from(exponent))
}
pub fn xbin(mantissa: i64, exponent: i64) -> XBinary {
XBinary::Finite(bin(mantissa, exponent))
}
pub fn unwrap_finite(input: &XBinary) -> Binary {
match input {
XBinary::Finite(value) => value.clone(),
XBinary::NegInf | XBinary::PosInf => {
panic!("expected finite extended binary, got {:?}", input)
}
}
}
pub fn unwrap_finite_uxbinary(input: &UXBinary) -> UBinary {
match input {
UXBinary::Finite(value) => value.clone(),
UXBinary::Inf => {
panic!("expected finite unsigned extended binary, got PosInf")
}
}
}
use crate::binary::{Bounds, FiniteBounds};
use crate::computable::Computable;
pub fn epsilon_as_binary(n: usize) -> Binary {
Binary::new(BigInt::from(1), BigInt::from(-(n as i64)))
}
pub fn midpoint_between(lower: &XBinary, upper: &XBinary) -> Binary {
let lower_finite = unwrap_finite(lower);
let upper_finite = unwrap_finite(upper);
FiniteBounds::new(lower_finite, upper_finite).midpoint()
}
pub fn interval_refine(state: Bounds) -> Result<Bounds, crate::error::ComputableError> {
let midpoint = midpoint_between(state.small(), &state.large());
Ok(Bounds::new(
XBinary::Finite(midpoint.clone()),
XBinary::Finite(midpoint),
))
}
pub fn interval_midpoint_computable(lower: i64, upper: i64) -> Computable {
let interval_state = Bounds::new(xbin(lower, 0), xbin(upper, 0));
Computable::new(
interval_state,
|inner_state| Ok(inner_state.clone()),
interval_refine,
)
}
pub fn interval_noop_computable(lower: i64, upper: i64) -> Computable {
let interval_state = Bounds::new(xbin(lower, 0), xbin(upper, 0));
Computable::new(interval_state, |state| Ok(state.clone()), |state| Ok(state))
}