scratch_test_value/math/
exp.rs1use crate::{QuirkSink, SNumber, quirks::SNumberToFloatQ};
2
3impl SNumber {
4 pub fn q_exp<Q>(&self, sink: &mut Q) -> SNumber
5 where
6 Q: QuirkSink<SNumberToFloatQ>,
7 {
8 SNumber::Float(self.q_as_float_nan_is_zero(sink).exp())
9 }
10
11 pub fn q_ln<Q>(&self, sink: &mut Q) -> SNumber
12 where
13 Q: QuirkSink<SNumberToFloatQ>,
14 {
15 Self::Float(self.q_as_float_nan_is_zero(sink).ln())
16 }
17
18 pub fn q_log10<Q>(&self, sink: &mut Q) -> SNumber
19 where
20 Q: QuirkSink<SNumberToFloatQ>,
21 {
22 Self::Float(self.q_as_float_nan_is_zero(sink).log10())
23 }
24
25 pub fn q_power_of_10<Q>(&self, sink: &mut Q) -> SNumber
33 where
34 Q: QuirkSink<SNumberToFloatQ>,
35 {
36 if let Self::Int(i) = self
37 && let Ok(exponent) = u32::try_from(*i)
38 && let Some(result) = 10_i64.checked_pow(exponent)
39 {
40 Self::Int(result)
41 } else {
42 Self::Float(10.0_f64.powf(self.q_as_float_nan_is_zero(sink)))
43 }
44 }
45
46 #[allow(unused)]
47 pub(crate) fn exp(&self) -> SNumber {
48 self.q_exp(&mut ())
49 }
50 #[allow(unused)]
51 pub(crate) fn ln(&self) -> SNumber {
52 self.q_ln(&mut ())
53 }
54 #[allow(unused)]
55 pub(crate) fn power_of_10(&self) -> SNumber {
56 self.q_power_of_10(&mut ())
57 }
58 #[allow(unused)]
59 pub(crate) fn log10(&self) -> SNumber {
60 self.q_log10(&mut ())
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use crate::SNumber;
67
68 #[test]
69 fn test_ln_special() {
70 assert_eq!(SNumber::NEG_INFINITY, SNumber::Float(0.0).ln());
71 assert_eq!(SNumber::POS_ZERO, SNumber::Float(1.0).ln());
72 assert_eq!(SNumber::NEG_ZERO, SNumber::Float(1.0).ln());
73 assert_eq!(SNumber::INFINITY, SNumber::INFINITY.ln());
74 assert_eq!(SNumber::NAN, SNumber::NEG_INFINITY.ln());
75 assert_eq!(SNumber::NEG_INFINITY, SNumber::NAN.ln());
76 }
77
78 #[test]
79 fn test_log10_special() {
80 assert_eq!(SNumber::NEG_INFINITY, SNumber::Float(0.0).log10());
81 assert_eq!(SNumber::POS_ZERO, SNumber::Float(1.0).log10());
82 assert_eq!(SNumber::NEG_ZERO, SNumber::Float(1.0).log10());
83 assert_eq!(SNumber::INFINITY, SNumber::INFINITY.log10());
84 assert_eq!(SNumber::NAN, SNumber::NEG_INFINITY.log10());
85 assert_eq!(SNumber::NEG_INFINITY, SNumber::NAN.log10());
86 }
87
88 #[test]
89 fn test_exp_special() {
90 assert_eq!(SNumber::Int(1), SNumber::Float(0.0).exp());
91 assert_eq!(SNumber::INFINITY, SNumber::INFINITY.exp());
92 assert_eq!(SNumber::POS_ZERO, SNumber::NEG_INFINITY.exp());
93 assert_eq!(SNumber::NEG_ZERO, SNumber::NEG_INFINITY.exp());
94 assert_eq!(SNumber::Float(1.0), SNumber::NAN.exp());
95 assert_eq!(SNumber::Int(1), SNumber::NAN.exp());
96
97 assert_eq!(SNumber::INFINITY, SNumber::Float(10000.0).exp());
98 }
99
100 #[test]
101 fn test_10_to_special() {
102 assert_eq!(SNumber::Int(1), SNumber::Float(0.0).power_of_10());
103 assert_eq!(SNumber::INFINITY, SNumber::INFINITY.power_of_10());
104 assert_eq!(SNumber::POS_ZERO, SNumber::NEG_INFINITY.power_of_10());
105 assert_eq!(SNumber::NEG_ZERO, SNumber::NEG_INFINITY.power_of_10());
106 assert_eq!(SNumber::Float(1.0), SNumber::NAN.power_of_10());
107 assert_eq!(SNumber::Int(1), SNumber::NAN.power_of_10());
108 }
109}