Skip to content

Commit

Permalink
ln impl and test
Browse files Browse the repository at this point in the history
  • Loading branch information
mihaicalinluca committed Jun 3, 2024
1 parent 7b839c6 commit 6fcfd36
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 0 deletions.
57 changes: 57 additions & 0 deletions framework/base/src/types/managed/wrapped/managed_decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,45 @@ impl<M: ManagedTypeApi, D: Decimals> ManagedDecimal<M, D> {
num_decimals,
)
}

// pub fn log<T: Decimals>(self, target_base: f64, precision: T) -> ManagedDecimal<M, T> {
// let num_decimals = f64::from(precision.num_decimals() as u32);
// let number = f64::from(self.data.to_u64().unwrap() as u32);

// assert!(number >= 1f64 && target_base >= 1f64, "wrong input");

// let precise = (number.log10() * num_decimals / target_base.log10())
// .trunc()
// .round() as u64;

// ManagedDecimal::from_raw_units(BigUint::<M>::from(precise), precision)
// }

pub fn ln(self, decimals: D) -> ManagedDecimal<M, NumDecimals> {
// find the highest power of 2 less than or equal to self
let log2 = self.data.log2(); // most significant bit
let divisor = 1 << log2;
let x = self.to_big_float() / BigFloat::from(divisor); // normalize to [1.0, 2.0]

let ln_of_2 = BigFloat::from_frac(69314718i64, 1_000_000_000i64);
let first = BigFloat::from_frac(17417939i64, 10_000_000i64); // 1.7417939, 7 decimals
let second = BigFloat::from_frac(28212026i64, 10_000_000i64); // 2.8212026, 7 decimals
let third = BigFloat::from_frac(14699568i64, 10_000_000i64); // 1.4699568, 7 decimals
let fourth = BigFloat::from_frac(44717955i64, 1_000_000_000i64); // 0.44717955, 9 decimals
let fifth = BigFloat::from_frac(56570851i64, 1_000_000_000i64); // 0.056570851, 9 decimals

// approximating polynom for getting the result
let result =
(((fourth - fifth * x.clone()) * x.clone() - third) * x.clone() + second) * x - first;
let add_member = BigFloat::from_big_uint(&BigUint::from(log2)) * ln_of_2;
let final_result = result + add_member;

final_result.to_managed_decimal(decimals.num_decimals())
}

pub fn nth_root(self, _root: ManagedDecimal<M, D>, _precision: D) -> ManagedDecimal<M, D> {
todo!()
}
}

impl<M: ManagedTypeApi, const DECIMALS: NumDecimals> ManagedDecimal<M, ConstDecimals<DECIMALS>> {
Expand Down Expand Up @@ -339,6 +378,24 @@ where
}
}

impl<M: ManagedTypeApi> Add<ManagedDecimal<M, NumDecimals>> for ManagedDecimal<M, NumDecimals> {
type Output = Self;

fn add(self, other: ManagedDecimal<M, NumDecimals>) -> Self::Output {
let scaled = other.rescale(self.scale());
ManagedDecimal::from_raw_units(&self.data + &scaled.data, scaled.decimals)
}
}

impl<M: ManagedTypeApi> Sub<ManagedDecimal<M, NumDecimals>> for ManagedDecimal<M, NumDecimals> {
type Output = Self;

fn sub(self, other: ManagedDecimal<M, NumDecimals>) -> Self::Output {
let scaled = other.rescale(self.scale());
ManagedDecimal::from_raw_units(&self.data - &scaled.data, scaled.decimals)
}
}

impl<M: ManagedTypeApi, D1: Decimals, D2: Decimals> PartialEq<ManagedDecimal<M, D2>>
for ManagedDecimal<M, D1>
{
Expand Down
84 changes: 84 additions & 0 deletions framework/scenario/tests/managed_decimal_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,87 @@ fn test_encode_decode() {

check_top_encode_decode(fixed_const, bytes);
}

#[test]
fn test_managed_decimal_ln() {
let fixed =
ManagedDecimal::<StaticApi, NumDecimals>::from_raw_units(BigUint::from(23u64), 0usize);

let ln_fixed = fixed.ln(10usize); // precision of 10 decimal points

println!("{ln_fixed:?}");
assert_eq!(
ln_fixed,
ManagedDecimal::<StaticApi, NumDecimals>::from_raw_units(
BigUint::from(313549421u64),
10usize
)
);
}

// #[test]
// fn test_managed_decimal_nth_root() {
// let fixed =
// ManagedDecimal::<StaticApi, NumDecimals>::from_raw_units(BigUint::from(567u64), 1usize);

// let fifth_root = fixed.clone().root(5f64, 100usize);
// let fifth_root_higher_prec = fixed.root(5f64, 100_000usize);

// assert_eq!(
// fifth_root,
// ManagedDecimal::<StaticApi, NumDecimals>::from_raw_units(BigUint::from(355u64), 100usize)
// );
// assert_eq!(
// fifth_root_higher_prec,
// ManagedDecimal::<StaticApi, NumDecimals>::from_raw_units(
// BigUint::from(355399u64),
// 100_000usize
// )
// );

// let const_fixed: ManagedDecimal<StaticApi, ConstDecimals<2>> =
// ManagedDecimal::<StaticApi, ConstDecimals<2>>::const_decimals_from_raw(BigUint::from(
// 876u64,
// ));

// let seventh_root_var = const_fixed.clone().root(7f64, 10_000usize);
// let seventh_root_const = const_fixed.root(7f64, ConstDecimals::<10_000>);

// assert_eq!(
// seventh_root_var,
// ManagedDecimal::<StaticApi, NumDecimals>::from_raw_units(
// BigUint::from(26324u64),
// 10_000usize
// )
// );
// assert_eq!(
// seventh_root_const,
// ManagedDecimal::<StaticApi, ConstDecimals::<10_000>>::const_decimals_from_raw(
// BigUint::from(26324u64)
// )
// );
// }

// #[test]
// fn test_managed_decimal_log_any_base() {
// let fixed = ManagedDecimal::from_raw_units(BigUint::from(10u64), 1usize);
// let log2_fixed = fixed.log(BigUint::from(2u64), 10_000usize);
// assert_eq!(
// log2_fixed,
// ManagedDecimal::<StaticApi, NumDecimals>::from_raw_units(
// BigUint::from(33219u64),
// 10_000usize
// )
// );

// let fixed_const = ManagedDecimal::<StaticApi, ConstDecimals<1>>::const_decimals_from_raw(
// BigUint::from(10u64),
// );
// let log2_const = fixed_const.log(BigUint::from(2u64), ConstDecimals::<10_000>);
// assert_eq!(
// log2_const,
// ManagedDecimal::<StaticApi, ConstDecimals::<10_000>>::const_decimals_from_raw(
// BigUint::from(33219u64)
// )
// );
// }

0 comments on commit 6fcfd36

Please sign in to comment.