pub struct NiceFloat<T: PrimitiveFloat>(pub T);
Expand description
NiceFloat
is a wrapper around primitive float types that provides nicer Eq
, Ord
,
Hash
, Display
, and FromStr
instances.
In most languages, floats behave weirdly due to the IEEE 754 standard. The NiceFloat
type
ignores the standard in favor of more intuitive behavior.
- Using
NiceFloat
,NaN
s are equal to themselves. There is a single, uniqueNaN
; there’s no concept of signallingNaN
s. Positive and negative zero are two distinct values, not equal to each other. - The
NiceFloat
hash respects this equality. NiceFloat
has a total order. These are the classes of floats, in ascending order:- Negative infinity
- Negative nonzero finite floats
- Negative zero
- NaN
- Positive zero
- Positive nonzero finite floats
- Positive infinity
NiceFloat
uses a differentDisplay
implementation than floats do by default in Rust. For example, Rust will formatf32::MIN_POSITIVE_SUBNORMAL
as something with many zeros, butNiceFloat(f32::MIN_POSITIVE_SUBNORMAL)
just formats it as"1.0e-45"
. The conversion function uses David Tolnay’sryu
crate, with a few modifications:- All finite floats have a decimal point. For example, Ryu by itself would convert
f32::MIN_POSITIVE_SUBNORMAL
to"1e-45"
. - Positive infinity, negative infinity, and NaN are converted to the strings
"Infinity"
,"-Infinity"
, and “NaN
”, respectively.
- All finite floats have a decimal point. For example, Ryu by itself would convert
FromStr
accepts these strings.
Tuple Fields
0: T
Trait Implementations
sourceimpl<T: Clone + PrimitiveFloat> Clone for NiceFloat<T>
impl<T: Clone + PrimitiveFloat> Clone for NiceFloat<T>
sourceimpl<T: PrimitiveFloat> Debug for NiceFloat<T>
impl<T: PrimitiveFloat> Debug for NiceFloat<T>
sourcefn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats a NiceFloat
as a string.
This is identical to the Display::fmt
implementation.
sourceimpl<T: Default + PrimitiveFloat> Default for NiceFloat<T>
impl<T: Default + PrimitiveFloat> Default for NiceFloat<T>
sourceimpl<T: PrimitiveFloat> Display for NiceFloat<T>
impl<T: PrimitiveFloat> Display for NiceFloat<T>
sourcefn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats a NiceFloat
as a string.
NiceFloat
uses a different Display
implementation than floats do by default in Rust.
For example, Rust will convert f32::MIN_POSITIVE_SUBNORMAL
to something with many zeros,
but NiceFloat(f32::MIN_POSITIVE_SUBNORMAL)
just converts to "1.0e-45"
. The conversion
function uses David Tolnay’s ryu
crate, with a few
modifications:
- All finite floats have a decimal point. For example, Ryu by itself would convert
f32::MIN_POSITIVE_SUBNORMAL
to"1e-45"
. - Positive infinity, negative infinity, and NaN are converted to the strings
"Infinity"
,"-Infinity"
, and “NaN
”, respectively.
Worst-case complexity
Constant time and additional memory.
Examples
use malachite_base::num::basic::floats::PrimitiveFloat;
use malachite_base::num::float::NiceFloat;
assert_eq!(NiceFloat(0.0).to_string(), "0.0");
assert_eq!(NiceFloat(-0.0).to_string(), "-0.0");
assert_eq!(NiceFloat(f32::POSITIVE_INFINITY).to_string(), "Infinity");
assert_eq!(NiceFloat(f32::NEGATIVE_INFINITY).to_string(), "-Infinity");
assert_eq!(NiceFloat(f32::NAN).to_string(), "NaN");
assert_eq!(NiceFloat(1.0).to_string(), "1.0");
assert_eq!(NiceFloat(-1.0).to_string(), "-1.0");
assert_eq!(
NiceFloat(f32::MIN_POSITIVE_SUBNORMAL).to_string(),
"1.0e-45"
);
assert_eq!(
NiceFloat(std::f64::consts::E).to_string(),
"2.718281828459045"
);
assert_eq!(
NiceFloat(std::f64::consts::PI).to_string(),
"3.141592653589793"
);
sourceimpl<T: PrimitiveFloat> FromStr for NiceFloat<T>
impl<T: PrimitiveFloat> FromStr for NiceFloat<T>
sourcefn from_str(src: &str) -> Result<NiceFloat<T>, <T as FromStr>::Err>
fn from_str(src: &str) -> Result<NiceFloat<T>, <T as FromStr>::Err>
Converts a &str
to a NiceFloat
.
If the &str
does not represent a valid NiceFloat
, an Err
is returned.
Worst-case complexity
$T(n) = O(n)$
$M(n) = O(1)$
where $T$ is time, $M$ is additional memory, and $n$ = src.len()
.
Examples
use malachite_base::num::float::NiceFloat;
use std::str::FromStr;
assert_eq!(NiceFloat::from_str("NaN").unwrap(), NiceFloat(f32::NAN));
assert_eq!(NiceFloat::from_str("-0.00").unwrap(), NiceFloat(-0.0f64));
assert_eq!(NiceFloat::from_str(".123").unwrap(), NiceFloat(0.123f32));
sourceimpl<T: PrimitiveFloat> Hash for NiceFloat<T>
impl<T: PrimitiveFloat> Hash for NiceFloat<T>
sourcefn hash<H: Hasher>(&self, state: &mut H)
fn hash<H: Hasher>(&self, state: &mut H)
Computes a hash of a NiceFloat
.
The hash is compatible with NiceFloat
equality: all NaN
s hash to the same value.
Worst-case complexity
Constant time and additional memory.
sourceimpl<T: PrimitiveFloat> Ord for NiceFloat<T>
impl<T: PrimitiveFloat> Ord for NiceFloat<T>
sourcefn cmp(&self, other: &NiceFloat<T>) -> Ordering
fn cmp(&self, other: &NiceFloat<T>) -> Ordering
Compares two NiceFloat
s.
This implementation ignores the IEEE 754 standard in favor of an equality operation that
respects the expected properties of symmetry, reflexivity, and transitivity. Using
NiceFloat
, NaN
s are equal to themselves. There is a single, unique NaN
; there’s no
concept of signalling NaN
s. Positive and negative zero are two distinct values, not equal
to each other.
Worst-case complexity
Constant time and additional memory.
Examples
use malachite_base::num::basic::floats::PrimitiveFloat;
use malachite_base::num::float::NiceFloat;
assert!(NiceFloat(0.0) > NiceFloat(-0.0));
assert!(NiceFloat(f32::NAN) < NiceFloat(0.0));
assert!(NiceFloat(f32::NAN) > NiceFloat(-0.0));
assert!(NiceFloat(f32::POSITIVE_INFINITY) > NiceFloat(f32::NAN));
assert!(NiceFloat(f32::NAN) < NiceFloat(1.0));
1.21.0 · sourcefn max(self, other: Self) -> Self
fn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
sourceimpl<T: PrimitiveFloat> PartialEq<NiceFloat<T>> for NiceFloat<T>
impl<T: PrimitiveFloat> PartialEq<NiceFloat<T>> for NiceFloat<T>
sourcefn eq(&self, other: &NiceFloat<T>) -> bool
fn eq(&self, other: &NiceFloat<T>) -> bool
Compares two NiceFloat
s for equality.
This implementation ignores the IEEE 754 standard in favor of a comparison operation that
respects the expected properties of antisymmetry, reflexivity, and transitivity.
NiceFloat
has a total order. These are the classes of floats, in ascending order:
- Negative infinity
- Negative nonzero finite floats
- Negative zero
- NaN
- Positive zero
- Positive nonzero finite floats
- Positive infinity
Worst-case complexity
Constant time and additional memory.
Examples
use malachite_base::num::float::NiceFloat;
assert_eq!(NiceFloat(0.0), NiceFloat(0.0));
assert_eq!(NiceFloat(f32::NAN), NiceFloat(f32::NAN));
assert_ne!(NiceFloat(f32::NAN), NiceFloat(0.0));
assert_ne!(NiceFloat(0.0), NiceFloat(-0.0));
assert_eq!(NiceFloat(1.0), NiceFloat(1.0));
sourceimpl<T: PrimitiveFloat> PartialOrd<NiceFloat<T>> for NiceFloat<T>
impl<T: PrimitiveFloat> PartialOrd<NiceFloat<T>> for NiceFloat<T>
sourcefn partial_cmp(&self, other: &NiceFloat<T>) -> Option<Ordering>
fn partial_cmp(&self, other: &NiceFloat<T>) -> Option<Ordering>
Compares a NiceFloat
to another NiceFloat
.
See the documentation for the Ord
implementation.
1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
fn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
impl<T: Copy + PrimitiveFloat> Copy for NiceFloat<T>
impl<T: PrimitiveFloat> Eq for NiceFloat<T>
Auto Trait Implementations
impl<T> RefUnwindSafe for NiceFloat<T> where
T: RefUnwindSafe,
impl<T> Send for NiceFloat<T> where
T: Send,
impl<T> Sync for NiceFloat<T> where
T: Sync,
impl<T> Unpin for NiceFloat<T> where
T: Unpin,
impl<T> UnwindSafe for NiceFloat<T> where
T: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more