dvcompute_dist/simulation/utils/
finite_f64.rs

1// Copyright (c) 2020-2022  David Sorokin <davsor@mail.ru>, based in Yoshkar-Ola, Russia
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
7use std::cmp::Ordering;
8use std::hash::Hash;
9use std::hash::Hasher;
10use std::mem;
11
12/// Represents a finite `f64` value.
13#[derive(Debug, Copy, Clone)]
14pub struct FiniteF64(pub f64);
15
16impl Hash for FiniteF64 {
17
18    fn hash<H: Hasher>(&self, state: &mut H) {
19
20        let x = self.0;
21
22        if x.is_finite() {
23            let key: u64 = unsafe { mem::transmute(x) };
24            key.hash(state)
25        } else {
26            0.hash(state)
27        }
28    }
29}
30
31impl PartialEq for FiniteF64 {
32
33    fn eq(&self, other: &Self) -> bool {
34
35        let x = self.0;
36        let y = other.0;
37
38        if !x.is_nan() {
39            x.eq(&y)
40        } else {
41            // consider all NaN to be equivalent, for we imply that this cannot be NaN
42            y.is_nan()
43        }
44    }
45}
46
47impl Eq for FiniteF64 {}
48
49impl PartialOrd for FiniteF64 {
50
51    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
52
53        let x = self.0;
54        let y = other.0;
55
56        x.partial_cmp(&y)
57    }
58}
59
60impl Ord for FiniteF64 {
61
62    fn cmp(&self, other: &Self) -> Ordering {
63
64        let x = self.0;
65        let y = other.0;
66
67        match x.partial_cmp(&y) {
68            Some(ordering) => ordering,
69            None if x.is_nan() => {
70                if y.is_nan() { Ordering::Equal } else { Ordering::Less }
71            },
72            None if y.is_nan() => {
73                if x.is_nan() { Ordering::Equal } else { Ordering::Greater }
74            },
75            None => {
76                // we cannot go to this line!
77                panic!("Illegal comparison of {} and {}", x, y)
78            }
79        }
80    }
81}