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}