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