concrete_commons/numeric/
float.rs1use std::ops::{
2 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
3};
4
5use super::Numeric;
6
7pub trait FloatingPoint:
9 Numeric
10 + Neg<Output = Self>
11 + Add<Self, Output = Self>
12 + AddAssign<Self>
13 + Div<Self, Output = Self>
14 + DivAssign<Self>
15 + Mul<Self, Output = Self>
16 + MulAssign<Self>
17 + Rem<Self, Output = Self>
18 + RemAssign<Self>
19 + Sub<Self, Output = Self>
20 + SubAssign<Self>
21{
22 #[must_use]
24 fn powi(self, power: i32) -> Self;
25
26 #[must_use]
28 fn round(self) -> Self;
29
30 #[must_use]
32 fn fract(self) -> Self;
33
34 #[must_use]
36 fn rem_euclid(self, rhs: Self) -> Self;
37
38 #[must_use]
40 fn sqrt(self) -> Self;
41
42 #[must_use]
44 fn ln(self) -> Self;
45
46 #[must_use]
48 fn abs(self) -> Self;
49
50 #[must_use]
52 fn floor(self) -> Self;
53
54 fn to_bit_string(&self) -> String;
57}
58
59macro_rules! implement {
60 ($Type: tt, $bits:expr) => {
61 impl Numeric for $Type {
62 const BITS: usize = $bits;
63 const ZERO: Self = 0.;
64 const ONE: Self = 1.;
65 const TWO: Self = 2.;
66 const MAX: Self = <$Type>::MAX;
67 }
68 impl FloatingPoint for $Type {
69 fn powi(self, power: i32) -> Self {
70 self.powi(power)
71 }
72 fn round(self) -> Self {
73 self.round()
74 }
75 fn fract(self) -> Self {
76 self.fract()
77 }
78 fn rem_euclid(self, rhs: Self) -> Self {
79 self.rem_euclid(rhs)
80 }
81 fn sqrt(self) -> Self {
82 self.sqrt()
83 }
84 fn ln(self) -> Self {
85 self.ln()
86 }
87 fn abs(self) -> Self {
88 self.abs()
89 }
90 fn floor(self) -> Self {
91 self.floor()
92 }
93 fn to_bit_string(&self) -> String {
94 if Self::BITS == 32 {
95 let mut bit_string = format!("{:032b}", self.to_bits());
96 bit_string.insert(1, ' ');
97 bit_string.insert(10, ' ');
98 format!("{}", bit_string)
99 } else {
100 let mut bit_string = format!("{:064b}", self.to_bits());
101 bit_string.insert(1, ' ');
102 bit_string.insert(13, ' ');
103 format!("{}", bit_string)
104 }
105 }
106 }
107 };
108}
109
110implement!(f64, 64);
111implement!(f32, 32);
112
113#[cfg(test)]
114mod test {
115 use super::*;
116
117 #[test]
118 fn test_f64_binary_rep() {
119 let a = 1123214.4321432_f64;
120 let b = a.to_bit_string();
121 assert_eq!(
122 b,
123 "0 10000010011 0001001000111000111001101110101000001110111111001111".to_string()
124 );
125 }
126
127 #[test]
128 fn test_f32_binary_rep() {
129 let a = -1.276_663_9e27_f32;
130 let b = a.to_bit_string();
131 assert_eq!(b, "1 11011001 00001000000000100000011".to_string());
132 }
133}