Skip to content

Commit

Permalink
improved common checks
Browse files Browse the repository at this point in the history
  • Loading branch information
DrunkRandomWalker committed Oct 27, 2023
1 parent 2ff258d commit 4a980fe
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 61 deletions.
9 changes: 2 additions & 7 deletions packages/injective-math/src/fp_decimal/exp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,17 +706,12 @@ impl FPDecimal {
(&FPDecimal::log11, FPDecimal::ELEVEN),
];
for (log_fn, divisor) in base_checks {
if log_fn(exponent).is_some() {
let value = log_fn(exponent).unwrap();
if let Some(value) = log_fn(exponent) {
if self == divisor {
return value;
}
}
if log_fn(self).is_some() {
let value = log_fn(self).unwrap();
if FPDecimal::ONE / value == exponent {
return divisor;
}
if let Some(value) = log_fn(self) {
if FPDecimal::ONE / value == exponent {
return divisor;
}
Expand Down
1 change: 1 addition & 0 deletions packages/injective-math/src/fp_decimal/from_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ mod tests {

#[test]
fn test_from_str_neg() {
//-0.69314718055994530943
assert_eq!((FPDecimal::ONE / FPDecimal::TWO).ln(), FPDecimal::must_from_str("-0.693147180435828445"));
assert_eq!(
(FPDecimal::ONE / FPDecimal::must_from_str("1.9")).ln(),
Expand Down
136 changes: 82 additions & 54 deletions packages/injective-math/src/fp_decimal/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,6 @@
use crate::fp_decimal::{FPDecimal, U256};

impl FPDecimal {
fn _log_const(self) -> Option<(FPDecimal, u128)> {
if let Some(value) = self.log2() {
return Some((value, 2u128));
}

if let Some(value) = self.log_e() {
//NOTE: base e can't be represented by u128, so we use 27 in here
return Some((value, 27u128));
}
if let Some(value) = self.log3() {
return Some((value, 3u128));
}
if let Some(value) = self.log5() {
return Some((value, 5u128));
}
if let Some(value) = self.log7() {
return Some((value, 7u128));
}
if let Some(value) = self.log10() {
return Some((value, 10u128));
}
if let Some(value) = self.log11() {
return Some((value, 11u128));
}
None
}

pub(crate) fn log_e(self) -> Option<FPDecimal> {
let e = FPDecimal::E;
if self == FPDecimal::ONE {
Expand Down Expand Up @@ -64,6 +37,10 @@ impl FPDecimal {
if self == e * e * e * e * e * e * e * e * e * e {
return Some(FPDecimal::TEN);
}
if self == e * e * e * e * e * e * e * e * e * e * e {
return Some(FPDecimal::ELEVEN);
}

if self == FPDecimal::ONE / FPDecimal::E {
return Some(-FPDecimal::ONE);
}
Expand Down Expand Up @@ -94,6 +71,9 @@ impl FPDecimal {
if self == FPDecimal::ONE / (e * e * e * e * e * e * e * e * e * e) {
return Some(-FPDecimal::TEN);
}
if self == FPDecimal::ONE / (e * e * e * e * e * e * e * e * e * e * e) {
return Some(-FPDecimal::ELEVEN);
}
None
}

Expand Down Expand Up @@ -131,6 +111,10 @@ impl FPDecimal {
if self == FPDecimal::from(1024u128) {
return Some(FPDecimal::TEN);
}
if self == FPDecimal::from(2048u128) {
return Some(FPDecimal::ELEVEN);
}

if self == FPDecimal::ONE / FPDecimal::TWO {
return Some(-FPDecimal::ONE);
}
Expand Down Expand Up @@ -161,6 +145,9 @@ impl FPDecimal {
if self == FPDecimal::ONE / FPDecimal::from(1024u128) {
return Some(-FPDecimal::TEN);
}
if self == FPDecimal::ONE / FPDecimal::from(2048u128) {
return Some(-FPDecimal::ELEVEN);
}
None
}

Expand Down Expand Up @@ -198,6 +185,9 @@ impl FPDecimal {
if self == FPDecimal::from(59049u128) {
return Some(FPDecimal::TEN);
}
if self == FPDecimal::from(177147u128) {
return Some(FPDecimal::ELEVEN);
}

if self == FPDecimal::ONE / FPDecimal::THREE {
return Some(-FPDecimal::ONE);
Expand Down Expand Up @@ -229,6 +219,10 @@ impl FPDecimal {
if self == FPDecimal::ONE / FPDecimal::from(59049u128) {
return Some(-FPDecimal::TEN);
}
if self == FPDecimal::ONE / FPDecimal::from(177147u128) {
return Some(-FPDecimal::ELEVEN);
}

None
}

Expand Down Expand Up @@ -266,6 +260,10 @@ impl FPDecimal {
if self == FPDecimal::from(9765625u128) {
return Some(FPDecimal::TEN);
}
if self == FPDecimal::from(48828125u128) {
return Some(FPDecimal::ELEVEN);
}

if self == FPDecimal::ONE / FPDecimal::FIVE {
return Some(-FPDecimal::ONE);
}
Expand Down Expand Up @@ -296,6 +294,10 @@ impl FPDecimal {
if self == FPDecimal::ONE / FPDecimal::from(9765625u128) {
return Some(-FPDecimal::TEN);
}
if self == FPDecimal::ONE / FPDecimal::from(48828125u128) {
return Some(-FPDecimal::ELEVEN);
}

None
}

Expand Down Expand Up @@ -334,6 +336,9 @@ impl FPDecimal {
if self == FPDecimal::from(282475249u128) {
return Some(FPDecimal::TEN);
}
if self == FPDecimal::from(1977326743u128) {
return Some(FPDecimal::ELEVEN);
}
if self == FPDecimal::ONE / FPDecimal::SEVEN {
return Some(-FPDecimal::ONE);
}
Expand Down Expand Up @@ -364,6 +369,10 @@ impl FPDecimal {
if self == FPDecimal::ONE / FPDecimal::from(282475249u128) {
return Some(-FPDecimal::TEN);
}
if self == FPDecimal::ONE / FPDecimal::from(1977326743u128) {
return Some(-FPDecimal::ELEVEN);
}

None
}

Expand Down Expand Up @@ -401,6 +410,9 @@ impl FPDecimal {
if self == FPDecimal::from(10_000_000_000u128) {
return Some(FPDecimal::TEN);
}
if self == FPDecimal::from(100_000_000_000u128) {
return Some(FPDecimal::ELEVEN);
}

if self == FPDecimal::ONE / FPDecimal::TEN {
return Some(-FPDecimal::ONE);
Expand Down Expand Up @@ -432,6 +444,9 @@ impl FPDecimal {
if self == FPDecimal::ONE / FPDecimal::from(10_000_000_000u128) {
return Some(-FPDecimal::TEN);
}
if self == FPDecimal::ONE / FPDecimal::from(100_000_000_000u128) {
return Some(-FPDecimal::ELEVEN);
}
None
}

Expand Down Expand Up @@ -470,6 +485,10 @@ impl FPDecimal {
if self == FPDecimal::from(25937424601u128) {
return Some(FPDecimal::TEN);
}
if self == FPDecimal::from(285311670611u128) {
return Some(FPDecimal::ELEVEN);
}

if self == FPDecimal::ONE / FPDecimal::ELEVEN {
return Some(-FPDecimal::ONE);
}
Expand Down Expand Up @@ -500,6 +519,10 @@ impl FPDecimal {
if self == FPDecimal::ONE / FPDecimal::from(25937424601u128) {
return Some(-FPDecimal::TEN);
}
if self == FPDecimal::ONE / FPDecimal::from(285311670611u128) {
return Some(-FPDecimal::ELEVEN);
}

None
}

Expand All @@ -517,7 +540,37 @@ impl FPDecimal {
a.ln() / base.ln()
}

#[allow(clippy::many_single_char_names)]
pub fn log(&self, base: FPDecimal) -> FPDecimal {
assert!(base > FPDecimal::ZERO);
if *self == FPDecimal::ONE {
return FPDecimal::ZERO;
}
if *self == FPDecimal::ZERO {
// FIXME should be an undefined, not sure if it will be better to just add assert!(b>0)
return FPDecimal::SMALLEST_PRECISION;
}

if base == FPDecimal::E {
return self.ln();
}

let base_checks: Vec<&dyn Fn(FPDecimal) -> Option<FPDecimal>> = vec![
&FPDecimal::log_e,
&FPDecimal::log2,
&FPDecimal::log3,
&FPDecimal::log5,
&FPDecimal::log7,
&FPDecimal::log10,
&FPDecimal::log11,
];
for log_fn in base_checks {
if let (Some(numerator), Some(denominator)) = (log_fn(*self), log_fn(base)) {
return numerator / denominator;
}
}
FPDecimal::_log(*self, base)
}

fn _two_agm(mut a0: FPDecimal, mut b0: FPDecimal, tol: FPDecimal) -> FPDecimal {
loop {
if (a0 - b0).abs() < tol {
Expand All @@ -536,6 +589,7 @@ impl FPDecimal {
// m =8, 2**8=256;
// m=16, 2**16=65536
// m=32, 2**32=4294967296
// m=64, 2**64=18446744073709551616
// m=128, 2**128=340282366920938463463374607431768211456
let two_pow_m = FPDecimal::from(4294967296u128);
let s = *self * two_pow_m;
Expand Down Expand Up @@ -629,32 +683,6 @@ impl FPDecimal {
}
self._ln()
}

pub fn log(&self, base: FPDecimal) -> FPDecimal {
assert!(base > FPDecimal::ZERO);
if *self == FPDecimal::ONE {
return FPDecimal::ZERO;
}
if *self == FPDecimal::ZERO {
// FIXME should be an undefined, not sure if it will be better to just add assert!(b>0)
return FPDecimal::SMALLEST_PRECISION;
}

if base == FPDecimal::E {
return self.ln();
}
let numerator = self._log_const();
let denominator = base._log_const();
match (numerator, denominator) {
(Some((n, nbase)), Some((d, dbase))) => {
if dbase == nbase {
return n / d;
}
FPDecimal::_log(*self, base)
}
(_, _) => FPDecimal::_log(*self, base),
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit 4a980fe

Please sign in to comment.