noisy_float/
checkers.rs

1// Copyright 2016-2021 Matthew D. Michelotti
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//   http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Standard implementations of `FloatChecker`.
16
17use crate::{FloatChecker, NoisyFloat};
18use num_traits::Float;
19
20/// A `FloatChecker` that considers all values valid except NaN.
21///
22/// This checks that the value is a "number", i.e. it is not "not-a-number".
23///
24/// The `assert` method is implemented using `debug_assert!`.
25pub struct NumChecker;
26
27impl<F: Float> FloatChecker<F> for NumChecker {
28    #[inline]
29    fn assert(value: F) {
30        debug_assert!(Self::check(value), "unexpected NaN");
31    }
32
33    #[inline]
34    fn check(value: F) -> bool {
35        !value.is_nan()
36    }
37}
38
39/// A `FloatChecker` that considers all values valid except NaN and +/- Infinity.
40///
41/// The `assert` method is implemented using `debug_assert!`.
42pub struct FiniteChecker;
43
44impl<F: Float> FloatChecker<F> for FiniteChecker {
45    #[inline]
46    fn assert(value: F) {
47        debug_assert!(Self::check(value), "unexpected NaN or infinity");
48    }
49
50    #[inline]
51    fn check(value: F) -> bool {
52        value.is_finite()
53    }
54}
55
56impl<F: Float> From<NoisyFloat<F, FiniteChecker>> for NoisyFloat<F, NumChecker> {
57    fn from(value: NoisyFloat<F, FiniteChecker>) -> Self {
58        Self::unchecked_new_generic(value.raw())
59    }
60}