1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
/*! This crate defines variants of the `f32` and `f64` types which *exclude* Not-a-Number. These types are collectively called "numeric". As a consequence of never being `NaN`, these types implement `Eq`, `Ord`, and `Hash`. They also attempt to define all relevant operations one would expect to be able to perform on floating-point numbers. The *problem* is what to do about operations that might result in `NaN`. The `n*f` types handle operations that result in `NaN` by instead returning the underlying `f*` result directly. For example, adding two `n32f`s results in an `f32`. The `n*p` types handle operations that result in `NaN` by *panicking* when `NaN` is produced. Some operations which panic also have `try_*` alternatives that return `Option<Self>` instead. # Supported Traits Where possible, the types in this crate implement all traits which are implemented on the corresponding `f*` type. In addition to those in the standard library, the following crates are also optionally supported: * [`conv`](https://crates.io/crates/conv/) * [`num`](https://crates.io/crates/num/) * [`rustc-serialize`](https://crates.io/crates/rustc-serialize/) * [`serde`](https://crates.io/crates/serde/) The following are explicitly *not* supported: * `DecodableFloat`, and `RawFloat` are internal and not stable to implement. * `One`, `Zero`, and `*Assign` are unstable. * [`ieee754`](https://crates.io/crates/ieee754/): the `Ieee754` trait *cannot* be implemented for new types. * `num`: `Float`, `Num`, `One`, `Signed`, and `Zero` *cannot* be implemented for `n*f`. */ #[macro_use] extern crate custom_derive; #[macro_use] extern crate newtype_derive; extern crate unreachable; #[cfg(feature="conv")] extern crate conv; #[cfg(feature="num")] extern crate num; #[cfg(feature="rustc-serialize")] extern crate rustc_serialize; #[cfg(feature="serde")] extern crate serde; pub use err::ParseNumericError; #[macro_use] mod macros; mod err; mod util; const NAN_MSG: &'static str = "operation resulted in NaN"; /** This trait is implemented for all numeric float types in this crate. */ pub trait Numeric { /// The corresponding "full float" type. type Float; } custom_derive! { /** A 32-bit floating point type which excludes Not-a-Number. Operations which would normally produce Not-a-Number instead result in `f32`. */ #[allow(non_camel_case_types)] #[derive(Copy, Clone, Default, PartialEq, PartialOrd, NumericImpl(option), RewrapFrom(n32p))] pub struct n32f(f32); } custom_derive! { /** A 64-bit floating point type which excludes Not-a-Number. Operations which would normally produce Not-a-Number instead result in `f64`. */ #[allow(non_camel_case_types)] #[derive(Copy, Clone, Default, PartialEq, PartialOrd, NumericImpl(option), RewrapFrom(n64p))] pub struct n64f(f64); } custom_derive! { /** A 32-bit floating point type which excludes Not-a-Number. Operations which would normally produce Not-a-Number instead panic. */ #[allow(non_camel_case_types)] #[derive(Copy, Clone, Default, PartialEq, PartialOrd, NumericImpl(panic), RewrapFrom(n32f))] pub struct n32p(f32); } custom_derive! { /** A 64-bit floating point type which excludes Not-a-Number. Operations which would normally produce Not-a-Number instead panic. */ #[allow(non_camel_case_types)] #[derive(Copy, Clone, Default, PartialEq, PartialOrd, NumericImpl(panic), RewrapFrom(n64f))] pub struct n64p(f64); }