|0.7.3||Nov 29, 2023|
#138 in Math
376 downloads per month
This crate helps you to ensure the kind of floats you are using, without
panic! (except if the
unsafe function is used in an unsound way).
zero overhead: everything is checked at compile time.
try_from adds a little overhead at runtime)
NaN is rejected by all types.
The 12 types provided by this crate are:
And their positive and negative counterparts:
(Negatives types reject
+0.0 and positives types reject
|Type||-∞||]-∞; -0.0[||-0.0||+0.0||]+0.0; +∞[||+∞||
The following conversions are implemented:
- Between all the types of this crate (of the same kind,
- From integers types (except
When to use it
When handling floats
When you handle floats, this crate can help you to ensure that you are not using
Infinity by mistake. Methods and functions implemented returns a type as strict as possible, so you know when you really have to check for
When writing a library
Using one of the type provided by this crate in your public API can help your users to avoid mistakes and limits the checks your functions have to do.
It also helps to make API simpler as you don't have to handle and document all the possible cases with
Infinity for example.
E.g. the following function:
fn fast_inv_sqrt(x: StrictlyPositiveFinite) -> StrictlyPositive;
- For the person implementing the API: the parameter
Infinity, and is strictly positive
- For the user: the result is not
NaNand is strictly positive but may be
It that example:
- the person implementing the API doesn't have to check for
<= 0for the parameter
- the user only have to check the result for
Infinityif they want to handle it differently and can't call the function with an invalid parameter.
Most methods and traits available on the underlying type are available on the types of this crate.
Most constants are also available, with the most appropriate
TypedFloat type (except
NAN for obvious reasons) in the
tf32 modules (in
tf32::consts respectively when the constant comes from
core::f32::consts). Those modules are named that way to avoid conflicts or confusion with the primitives
As none of the types of this crate can be
NaN, the following traits are implemented on all 12 types:
- deprecated and nightly-only methods
- total_cmp(&self, other: &f64) -> Ordering
- sin_cos(self) -> (f64, f64)
- mul_add(self, a: f64, b: f64) -> f64
- clamp(self, min: f64, max: f64) -> f64
The only method that can
panic! is the
new_unchecked when used in an invalid way.
panic! triggered in any other way is considered a security bug and should be reported.
This crate is designed to have a minimal overhead at runtime, in terms of memory, speed and binary size.
The only methods that adds a little overhead are
try_from because of the checks they do at runtime, compared to the
In debug mode, a little overhead is present, both to check the validity of the values and because
inline may not be respected.
Any other overhead is considered a bug and should be reported.
std: enabled by default, gives all
libm: use the
libmto implement the missing methods when the
stdfeature is disabled. Side effect:
num-traits. When both
libmfeatures are enabled, the
stdimplementation is used.
How it works
For each operation, at compile time crate determine the most strict type possible for the result.
Methods that takes another float as parameter will also return the most strict type possible depending on the both types. For the methods where a trait is not available to specify the return type depending on the parameter type, a new trait is created:
- Doesn't fix the floating point quirks such as
0.0 == -0.0
- Doesn't fix the odd methods such as:
Because that would introduce a runtime overhead and may introduce some incompatibilities with existing code.
This crate is tested when a new version is release with:
- Rust beta
- Rust stable
- Rust 1.70.0
Also, tests on
stable are run weekly on GitHub actions.
The minimum supported Rust version is 1.70.0 because of the use of
Cargo.toml and the usage of
To run all tests:
git clone https://github.com/tdelmas/typed_floats cd typed_floats # generate the published documentation, including some tests cargo xtask pre-build cargo test --all
- checked-float A crate for making invariant-enforcing floating point wrappers
- decorum Decorum is a Rust library that provides total ordering, equivalence, hashing, and constraints for floating-point representations. Decorum does not require std.
- eq-float Float wrappers with a total order (by setting NAN == NAN).
- fix_float Fixed floating types that allows useful trait implementations and datastructures on float numbers
- float-derive A crate that allows deriving Eq and Hash for types that contain floating points.
- float-ord A total ordering for floating-point numbers.
- nanbox NaN boxing implementation.
- noisy_float Contains floating point types that panic if they are set to an illegal value, such as NaN.
- num-order Numerically consistent
Hashimplementations for various
- ordered-float Provides several wrapper types for Ord and Eq implementations on f64 and friends.
maxfunctions that work with
- real_float Floating point types that check for correctness and implement total ordering.
- result_float Floating point type that cannot store NaN.
- totally-ordered No dependency, no-std totally ordered f32/f64
- unsigned-f64 A wrapper around f64 that guarantees that the value is always non-negative on the type level.
Features provided/checked by those crates:
✔️: provided, ❌: not provided, ❓: unknown
(you may need to scroll to the right to see all the columns: "Production ready", "Avoid
panic!", "Minimal overhead", "Eq/Ord", "Hash", "NaN", "Inf", "Zero", "Positive", "Negative")
(N.B. "Production ready" is a subjective measure)
¹: Can be manually checked
Is on docs.rs.