1
- use super :: run_length_encodable:: FloatingStep ;
2
- use super :: { FloatIsNaN , FloorToUsize , RunLengthEncodable } ;
3
- use crate :: error:: Error ;
4
- use crate :: function:: definitions:: numeric:: traits:: { CheckedPow , CheckedSquareRoot } ;
5
- use num:: traits:: CheckedNeg ;
6
- use num:: { Bounded , CheckedAdd , CheckedDiv , CheckedMul , CheckedSub , FromPrimitive , One , Zero } ;
7
- use std:: cmp:: Ordering ;
8
- use std:: fmt;
9
- use std:: iter:: { Product , Sum } ;
10
- use std:: ops:: { Add , AddAssign , Div , DivAssign , Mul , MulAssign , Rem , Sub , SubAssign } ;
1
+ //! This module defines a wrapper type [Float] for [f32] that excludes NaN and infinity.
2
+
3
+ use std:: {
4
+ cmp:: Ordering ,
5
+ fmt,
6
+ iter:: { Product , Sum } ,
7
+ ops:: { Add , AddAssign , Div , DivAssign , Mul , MulAssign , Rem , Sub , SubAssign } ,
8
+ } ;
9
+
10
+ use num:: {
11
+ traits:: CheckedNeg , Bounded , CheckedAdd , CheckedDiv , CheckedMul , CheckedSub , FromPrimitive ,
12
+ One , Zero ,
13
+ } ;
14
+
15
+ use super :: { run_length_encodable:: FloatingStep , FloorToUsize , RunLengthEncodable } ;
16
+ use crate :: {
17
+ error:: { Error , ReadingError } ,
18
+ function:: definitions:: numeric:: traits:: { CheckedPow , CheckedSquareRoot } ,
19
+ } ;
11
20
12
21
#[ cfg( test) ]
13
22
use quickcheck:: { Arbitrary , Gen } ;
14
23
15
- /// Wrapper for [f32` ] that does not allow [` f32::NAN] values.
24
+ /// Wrapper for [f32] that excludes [ f32::NAN] and infinite values
16
25
#[ derive( Copy , Clone , Debug , PartialEq , Default ) ]
17
26
pub struct Float ( f32 ) ;
18
27
19
28
impl Float {
20
29
/// Wraps the given [f32]-`value` as a value over [Float].
21
30
///
22
31
/// # Errors
23
- /// The given `value` is [f32::NAN].
24
- pub fn new ( value : f32 ) -> Result < Self , Error > {
25
- if value. is_nan ( ) {
26
- return Err ( Error :: ReadingError ( FloatIsNaN . into ( ) ) ) ;
32
+ /// Returns an error if `value` is [f32::NAN] or infinite .
33
+ pub fn new ( value : f32 ) -> Result < Self , ReadingError > {
34
+ if ! value. is_finite ( ) {
35
+ return Err ( ReadingError :: InvalidFloat ) ;
27
36
}
28
37
29
38
Ok ( Float ( value) )
30
39
}
31
40
32
- /// Wraps the given [f32]-`value`, that is a number, as a value over [Float].
41
+ /// Wraps the given [f32]-`value` as a value over [Float].
33
42
///
34
43
/// # Panics
35
- /// The given `value` is [f32::NAN].
44
+ /// Panics if `value` is [f32::NAN] or not finite .
36
45
pub fn from_number ( value : f32 ) -> Self {
37
- if value. is_nan ( ) {
38
- panic ! ( "The provided value is not a number (NaN)! " )
46
+ if ! value. is_finite ( ) {
47
+ panic ! ( "floating point values must be finite " )
39
48
}
40
49
41
50
Float ( value)
42
51
}
43
52
44
53
/// Computes the absolute value.
45
54
pub ( crate ) fn abs ( self ) -> Self {
46
- Float :: new ( self . 0 . abs ( ) ) . expect ( "Taking the absolute value cannot result in NaN " )
55
+ Float :: new ( self . 0 . abs ( ) ) . expect ( "operation returns valid float " )
47
56
}
48
57
49
58
/// Returns the logarithm of the number with respect to an arbitrary base.
@@ -53,33 +62,33 @@ impl Float {
53
62
54
63
/// Computes the sine of a number (in radians).
55
64
pub ( crate ) fn sin ( self ) -> Self {
56
- Float :: new ( self . 0 . sin ( ) ) . expect ( "Operation does not result in NaN " )
65
+ Float :: new ( self . 0 . sin ( ) ) . expect ( "operation returns valid float " )
57
66
}
58
67
59
68
/// Computes the cosine of a number (in radians).
60
69
pub ( crate ) fn cos ( self ) -> Self {
61
- Float :: new ( self . 0 . cos ( ) ) . expect ( "Operation does not result in NaN " )
70
+ Float :: new ( self . 0 . cos ( ) ) . expect ( "operation returns valid float " )
62
71
}
63
72
64
73
/// Computes the tangent of a number (in radians).
65
74
pub ( crate ) fn tan ( self ) -> Self {
66
- Float :: new ( self . 0 . tan ( ) ) . expect ( "Operation does not result in NaN " )
75
+ Float :: new ( self . 0 . tan ( ) ) . expect ( "operation returns valid float " )
67
76
}
68
77
69
78
/// Returns the nearest integer to `self`.
70
79
/// If a value is half-way between two integers, round away from 0.0.
71
80
pub ( crate ) fn round ( self ) -> Self {
72
- Float :: new ( self . 0 . round ( ) ) . expect ( "Operation does not result in NaN " )
81
+ Float :: new ( self . 0 . round ( ) ) . expect ( "operation returns valid float " )
73
82
}
74
83
75
84
/// Returns the smallest integer greater than or equal to `self`.
76
85
pub ( crate ) fn ceil ( self ) -> Self {
77
- Float :: new ( self . 0 . ceil ( ) ) . expect ( "Operation does not result in NaN " )
86
+ Float :: new ( self . 0 . ceil ( ) ) . expect ( "operation returns valid float " )
78
87
}
79
88
80
89
/// Returns the largest integer less than or equal to `self`.
81
90
pub ( crate ) fn floor ( self ) -> Self {
82
- Float :: new ( self . 0 . floor ( ) ) . expect ( "Operation does not result in NaN " )
91
+ Float :: new ( self . 0 . floor ( ) ) . expect ( "operation returns valid float " )
83
92
}
84
93
}
85
94
@@ -95,7 +104,7 @@ impl Ord for Float {
95
104
fn cmp ( & self , other : & Self ) -> Ordering {
96
105
self . 0
97
106
. partial_cmp ( & other. 0 )
98
- . expect ( "Comparison can only fail on NaN values which have been forbidden in this type" )
107
+ . expect ( "comparison can only fail on NaN values which have been forbidden in this type" )
99
108
}
100
109
}
101
110
@@ -170,7 +179,7 @@ impl fmt::Display for Float {
170
179
}
171
180
172
181
impl TryFrom < f32 > for Float {
173
- type Error = Error ;
182
+ type Error = ReadingError ;
174
183
175
184
fn try_from ( value : f32 ) -> Result < Self , Self :: Error > {
176
185
Self :: new ( value)
@@ -187,9 +196,9 @@ impl TryFrom<usize> for Float {
187
196
type Error = Error ;
188
197
189
198
fn try_from ( value : usize ) -> Result < Self , Self :: Error > {
190
- f32:: from_usize ( value)
191
- . ok_or ( Error :: UsizeToFloatingPointValue ( value ) )
192
- . and_then ( Float :: new)
199
+ let res = f32:: from_usize ( value) . ok_or ( Error :: UsizeToFloatingPointValue ( value ) ) ? ;
200
+
201
+ Ok ( Float :: new ( res ) ? )
193
202
}
194
203
}
195
204
@@ -293,7 +302,7 @@ impl Bounded for Float {
293
302
impl Arbitrary for Float {
294
303
fn arbitrary ( g : & mut Gen ) -> Self {
295
304
let mut value = f32:: arbitrary ( g) ;
296
- while value. is_nan ( ) {
305
+ while ! value. is_finite ( ) {
297
306
value = f32:: arbitrary ( g) ;
298
307
}
299
308
0 commit comments