**Decorum** is a Rust library that provides total ordering, equivalence,
hashing, and constraints for floating-point representations. Decorum does not
require `std`

.

## Total Ordering

The following total ordering is exposed via traits for primitive types and proxy
types that implement `Ord`

:

```
[ -INF < ... < 0 < ... < +INF < NaN ]
```

IEEE-754 floating-point encoding provides multiple representations of zero (`-0`

and `+0`

) and `NaN`

. This ordering considers all zero and `NaN`

representations
equal, which differs from the standard partial
ordering.

Some proxy types disallow unordered `NaN`

values and therefore support a total
ordering based on the ordered subset of non-`NaN`

floating-point values (see
below).

## Proxy Types

Decorum exposes several proxy (wrapper) types. Proxy types provide two primary
features: they implement total ordering and equivalence via the `Eq`

, `Ord`

, and
`Hash`

traits and they constrain the class of floating-point values they can
represent. Different type definitions apply different constraints, with the
`Total`

type applying no constraints at all.

Type | Aliases | Trait Implementations | Disallowed Values |
---|---|---|---|

`Total` |
`Encoding + Real + Infinite + Nan + Float` |
||

`NotNan` |
`N32` , `N64` |
`Encoding + Real + Infinite` |
`NaN` |

`Finite` |
`R32` , `R64` |
`Encoding + Real` |
`NaN` , `-INF` , `+INF` |

Proxy types implement common operation traits, such as `Add`

and `Mul`

. These
types also implement numeric traits from the `num-traits`

crate (such as
`Float`

, `Num`

, `NumCast`

, etc.), in addition to more targeted traits like
`Real`

and `Nan`

provided by Decorum.

Constraint violations cause panics. For example, `NotNan`

is useful for avoiding
or tracing sources of `NaN`

s in computation, while `Total`

provides useful
features without introducing any panics at all, because it allows any IEEE-754
floating-point values.

Proxy types should work as a drop-in replacement for primitive types in most
applications with the most common exception being initialization (because it
requires a conversion). Serialization is optionally supported with `serde`

and
approximate comparisons are optionally supported with `approx`

via the
`serialize-serde`

and `approx`

features, respectively.

## Traits

Traits are essential for generic programming, but the constraints used by some
proxy types prevent them from implementing the `Float`

trait, because it implies
the presence of `-INF`

, `+INF`

, and `NaN`

(and their corresponding trait
implementations).

Decorum provides more granular traits that separate these APIs: `Real`

,
`Infinite`

, `Nan`

, and `Encoding`

. Primitive floating-point types implement all
of these traits and proxy types implement traits that are consistent with their
constraints.

For example, code that wishes to be generic over floating-point types
representing real numbers and infinities can use a bound on the `Infinite`

and
`Real`

traits:

```
use ;
```

Both Decorum and `num-traits`

provide `Real`

and `Float`

traits. These traits
are somewhat different and are not always interchangeable. Traits from both
crates are implemented by Decorum where possible. For example, `Total`

implements `Float`

from both Decorum and `num-traits`

.

## Conversions

Proxy types are used via conversions to and from primitive floating-point types and other proxy types.

Conversion | Input | Output | Violation |
---|---|---|---|

`from_inner` |
primitive | proxy | panic |

`into_inner` |
proxy | primitive | n/a |

`from_subset` |
proxy | proxy | n/a |

`into_superset` |
proxy | proxy | n/a |

The `from_inner`

and `into_inner`

conversions move primitive floating-point
values into and out of proxies. The `into_superset`

and `from_subset`

conversions provide an inexpensive way to convert between proxy types with
different but compatible constraints. All conversions also support the standard
`From`

and `Into`

traits, which can also be applied to literals:

```
use R32;
let y: R32 = 3.1459.into;
let z = f;
let w: f32 = z.into;
```

## Primitives

Proxy types implement `Eq`

, `Hash`

, and `Ord`

, but sometimes it is not
possible or ergonomic to use such a type. Traits can be used with primitive
floating-point values for ordering, equivalence, and hashing instead.

Floating-Point Trait | General Trait |
---|---|

`FloatEq` |
`Eq` |

`FloatHash` |
`Hash` |

`FloatOrd` |
`Ord` |

These traits use the same total ordering and equivalence rules that proxy types do. They are implemented for base types as well as slices:

```
use FloatEq;
let x = 0.0f64 / 0.0f64; // `NaN`.
let y = f64INFINITY + f64NEG_INFINITY; // `NaN`.
assert!;
let xs = ;
let ys = ;
assert!;
```