measurements/
frequency.rs1use super::measurement::*;
4use crate::time;
5
6pub const HERTZ_NANOHERTZ_FACTOR: f64 = 1e9;
8pub const HERTZ_MICROHERTZ_FACTOR: f64 = 1e6;
10pub const HERTZ_MILLIHERTZ_FACTOR: f64 = 1e3;
12pub const HERTZ_KILOHERTZ_FACTOR: f64 = 1e-3;
14pub const HERTZ_MEGAHERTZ_FACTOR: f64 = 1e-6;
16pub const HERTZ_GIGAHERTZ_FACTOR: f64 = 1e-9;
18pub const HERTZ_TERAHERTZ_FACTOR: f64 = 1e-12;
20
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
33#[derive(Copy, Clone, Debug, Default)]
34pub struct Frequency {
35 hertz: f64,
36}
37
38pub type Distance = Frequency;
40
41impl Frequency {
42 pub fn from_hertz(hertz: f64) -> Self {
44 Frequency { hertz }
45 }
46
47 pub fn from_nanohertz(nanohertz: f64) -> Self {
49 Self::from_hertz(nanohertz / HERTZ_NANOHERTZ_FACTOR)
50 }
51
52 pub fn from_microhertz(microhertz: f64) -> Self {
54 Self::from_hertz(microhertz / HERTZ_MICROHERTZ_FACTOR)
55 }
56
57 pub fn from_millihertz(millihertz: f64) -> Self {
59 Self::from_hertz(millihertz / HERTZ_MILLIHERTZ_FACTOR)
60 }
61
62 pub fn from_kilohertz(kilohertz: f64) -> Self {
64 Self::from_hertz(kilohertz / HERTZ_KILOHERTZ_FACTOR)
65 }
66
67 pub fn from_megahertz(megahertz: f64) -> Self {
69 Self::from_hertz(megahertz / HERTZ_MEGAHERTZ_FACTOR)
70 }
71
72 pub fn from_gigahertz(gigahertz: f64) -> Self {
74 Self::from_hertz(gigahertz / HERTZ_GIGAHERTZ_FACTOR)
75 }
76
77 pub fn from_terahertz(terahertz: f64) -> Self {
79 Self::from_hertz(terahertz / HERTZ_TERAHERTZ_FACTOR)
80 }
81
82 pub fn from_period(period: time::Duration) -> Self {
84 Self::from_hertz(1.0 / period.as_base_units())
85 }
86
87 pub fn as_nanohertz(&self) -> f64 {
89 self.hertz * HERTZ_NANOHERTZ_FACTOR
90 }
91
92 pub fn as_microhertz(&self) -> f64 {
94 self.hertz * HERTZ_MICROHERTZ_FACTOR
95 }
96
97 pub fn as_millihertz(&self) -> f64 {
99 self.hertz * HERTZ_MILLIHERTZ_FACTOR
100 }
101
102 pub fn as_hertz(&self) -> f64 {
104 self.hertz
105 }
106
107 pub fn as_kilohertz(&self) -> f64 {
109 self.hertz * HERTZ_KILOHERTZ_FACTOR
110 }
111
112 pub fn as_megahertz(&self) -> f64 {
114 self.hertz * HERTZ_MEGAHERTZ_FACTOR
115 }
116
117 pub fn as_gigahertz(&self) -> f64 {
119 self.hertz * HERTZ_GIGAHERTZ_FACTOR
120 }
121
122 pub fn as_terahertz(&self) -> f64 {
124 self.hertz * HERTZ_TERAHERTZ_FACTOR
125 }
126
127 pub fn as_period(&self) -> time::Duration {
129 time::Duration::from_base_units(1.0 / self.hertz)
130 }
131}
132
133impl Measurement for Frequency {
134 fn get_appropriate_units(&self) -> (&'static str, f64) {
135 let list = [
137 ("nHz", 1e-9),
138 ("\u{00B5}Hz", 1e-6),
139 ("mHz", 1e-3),
140 ("Hz", 1e0),
141 ("kHz", 1e3),
142 ("MHz", 1e6),
143 ("GHz", 1e9),
144 ("THz", 1e12),
145 ];
146 self.pick_appropriate_units(&list)
147 }
148
149 fn get_base_units_name(&self) -> &'static str {
150 "Hz"
151 }
152
153 fn as_base_units(&self) -> f64 {
154 self.hertz
155 }
156
157 fn from_base_units(units: f64) -> Self {
158 Self::from_hertz(units)
159 }
160}
161
162implement_measurement! { Frequency }
163
164#[cfg(test)]
165mod test {
166 use super::*;
167 use crate::{test_utils::assert_almost_eq, time};
168
169 #[test]
170 pub fn hertz() {
171 let i1 = Frequency::from_hertz(100.0);
172 let r1 = i1.as_hertz();
173 assert_almost_eq(r1, 100.0);
174 }
175
176 #[test]
177 pub fn nanohertz() {
178 let i1 = Frequency::from_hertz(100.0);
179 let r1 = i1.as_nanohertz();
180 let i2 = Frequency::from_nanohertz(100.0);
181 let r2 = i2.as_hertz();
182 assert_almost_eq(r1, 1e+11);
183 assert_almost_eq(r2, 1e-7);
184 }
185
186 #[test]
187 pub fn microhertz() {
188 let i1 = Frequency::from_hertz(100.0);
189 let r1 = i1.as_microhertz();
190 let i2 = Frequency::from_microhertz(100.0);
191 let r2 = i2.as_hertz();
192 assert_almost_eq(r1, 1e+8);
193 assert_almost_eq(r2, 1e-4);
194 }
195
196 #[test]
197 pub fn millihertz() {
198 let i1 = Frequency::from_hertz(100.0);
199 let r1 = i1.as_millihertz();
200 let i2 = Frequency::from_millihertz(100.0);
201 let r2 = i2.as_hertz();
202 assert_almost_eq(r1, 1e+5);
203 assert_almost_eq(r2, 1e-1);
204 }
205
206 #[test]
207 pub fn kilohertz() {
208 let i1 = Frequency::from_hertz(100.0);
209 let r1 = i1.as_kilohertz();
210 let i2 = Frequency::from_kilohertz(100.0);
211 let r2 = i2.as_hertz();
212 assert_almost_eq(r1, 1e-1);
213 assert_almost_eq(r2, 1e+5);
214 }
215
216 #[test]
217 pub fn megahertz() {
218 let i1 = Frequency::from_hertz(100.0);
219 let r1 = i1.as_megahertz();
220 let i2 = Frequency::from_megahertz(100.0);
221 let r2 = i2.as_hertz();
222 assert_almost_eq(r1, 1e-4);
223 assert_almost_eq(r2, 1e+8);
224 }
225
226 #[test]
227 pub fn gigahertz() {
228 let i1 = Frequency::from_hertz(100.0);
229 let r1 = i1.as_gigahertz();
230 let i2 = Frequency::from_gigahertz(100.0);
231 let r2 = i2.as_hertz();
232 assert_almost_eq(r1, 1e-7);
233 assert_almost_eq(r2, 1e+11);
234 }
235
236 #[test]
237 pub fn terahertz() {
238 let i1 = Frequency::from_hertz(100.0);
239 let r1 = i1.as_terahertz();
240 let i2 = Frequency::from_terahertz(100.0);
241 let r2 = i2.as_hertz();
242 assert_almost_eq(r1, 1e-10);
243 assert_almost_eq(r2, 1e+14);
244 }
245
246 #[test]
247 pub fn period() {
248 let i1 = Frequency::from_hertz(100.0);
249 let r1 = i1.as_period().as_base_units();
250 let i2 = Frequency::from_period(time::Duration::new(100, 0));
251 let r2 = i2.as_hertz();
252 assert_almost_eq(r1, 1e-2);
253 assert_almost_eq(r2, 1e-2);
254 }
255
256 #[test]
258 fn add() {
259 let a = Frequency::from_hertz(2.0);
260 let b = Frequency::from_hertz(4.0);
261 let c = a + b;
262 let d = b + a;
263 assert_almost_eq(c.as_hertz(), 6.0);
264 assert_eq!(c, d);
265 }
266
267 #[test]
268 fn sub() {
269 let a = Frequency::from_hertz(2.0);
270 let b = Frequency::from_hertz(4.0);
271 let c = a - b;
272 assert_almost_eq(c.as_hertz(), -2.0);
273 }
274
275 #[test]
276 fn mul() {
277 let a = Frequency::from_hertz(3.0);
278 let b = a * 2.0;
279 let c = 2.0 * a;
280 assert_almost_eq(b.as_hertz(), 6.0);
281 assert_eq!(b, c);
282 }
283
284 #[test]
285 fn div() {
286 let a = Frequency::from_hertz(2.0);
287 let b = Frequency::from_hertz(4.0);
288 let c = a / b;
289 let d = a / 2.0;
290 assert_almost_eq(c, 0.5);
291 assert_almost_eq(d.as_hertz(), 1.0);
292 }
293
294 #[test]
295 fn eq() {
296 let a = Frequency::from_hertz(2.0);
297 let b = Frequency::from_hertz(2.0);
298 assert_eq!(a == b, true);
299 }
300
301 #[test]
302 fn neq() {
303 let a = Frequency::from_hertz(2.0);
304 let b = Frequency::from_hertz(4.0);
305 assert_eq!(a == b, false);
306 }
307
308 #[test]
309 fn cmp() {
310 let a = Frequency::from_hertz(2.0);
311 let b = Frequency::from_hertz(4.0);
312 assert_eq!(a < b, true);
313 assert_eq!(a <= b, true);
314 assert_eq!(a > b, false);
315 assert_eq!(a >= b, false);
316 }
317}