19个版本
0.3.1 | 2020年5月31日 |
---|---|
0.2.0 | 2020年5月4日 |
0.1.3 | 2019年1月11日 |
0.1.2 | 2018年12月1日 |
0.0.7 | 2017年11月15日 |
#162 在 Rust模式
50,384 每月下载
用于 54 个crate (25直接)
90KB
2.5K SLoC
Decorum 是一个Rust库,它为浮点表示提供全序、等价、哈希和约束。Decorum不需要std
。
全序
以下全序通过实现Ord
的原始类型和代理类型(proxy types)的特质公开
[ -INF < ... < 0 < ... < +INF < NaN ]
IEEE-754浮点编码提供了多种零(-0 和
+0
)和 NaN
的表示。此排序将所有零和 NaN
表示视为相等,这与 标准部分排序 不同。
某些代理类型不允许无序的 NaN
值,因此支持基于非 NaN
浮点值有序子集的全序(见下文)。
代理类型
Decorum公开了几个代理(包装)类型。代理类型提供了两个主要功能:它们通过Eq
、Ord
和Hash
特质实现全序和等价,并且它们约束它们可以表示的浮点值类别。不同的类型定义应用不同的约束,其中Total
类型不施加任何约束。
类型 | 别名 | 特质实现 | 不允许的值 |
---|---|---|---|
全序 |
编码+实数+无穷大+NaN+浮点数 |
||
非NaN |
N32 , N64 |
编码+实数+无穷大 |
NaN |
有限 |
R32 , R64 |
编码+实数 |
NaN , -INF , +INF |
代理类型实现了常见的操作特性,例如 Add
和 Mul
。这些类型还实现了来自 num-traits
包(例如 Float
、Num
、NumCast
等)的数值特性,以及 Decorum 提供的更具体的特性,如 Real
和 Nan
。
约束违规会导致 panic。例如,NotNan
有助于避免或追踪计算中 NaN
的来源,而 Total
提供了有用的功能,而不会引起任何 panic,因为它允许任何 IEEE-754 浮点值。
代理类型应作为原始类型在大多数应用程序中的直接替换,最常见的例外是初始化(因为它需要转换)。序列化可选支持 serde
,并通过 serialize-serde
和 approx
功能分别支持近似比较。
特性
特性对于泛型编程至关重要,但某些代理类型使用的约束阻止它们实现 Float
特性,因为它暗示了 -INF
、+INF
和 NaN
(以及它们对应的特性实现)的存在。
Decorum 提供了更细粒度的特性,这些特性将这些 API 区分开来:Real
、Infinite
、Nan
和 Encoding
。原始浮点类型实现了所有这些特性,代理类型实现了与其约束一致的特性。
例如,希望泛型处理表示实数和无穷大的浮点类型的代码可以使用 Infinite
和 Real
特性的界限
use decorum::{Infinite, Real};
fn f<T>(x: T, y: T) -> T
where
T: Infinite + Real,
{
let z = x / y;
if z.is_infinite() {
y
}
else {
z
}
}
Decorum 和 num-traits
都提供了 Real
和 Float
特性。这些特性有些不同,并不总是可互换的。Decorum 尽可能地实现了两个包中的特性。例如,Total
实现了来自 Decorum 和 num-traits
的 Float
。
转换
代理类型通过转换为原始浮点类型和其他代理类型来使用。
转换 | 输入 | 输出 | 违规 |
---|---|---|---|
from_inner |
原始类型 | 代理类型 | panic |
into_inner |
代理类型 | 原始类型 | n/a |
from_subset |
代理类型 | 代理类型 | n/a |
into_superset |
代理类型 | 代理类型 | n/a |
from_inner
和 into_inner
转换将原始浮点值移动到代理中并从代理中移出。into_superset
和 from_subset
转换提供了在不同但兼容的约束之间转换的低成本方法。所有转换还支持标准的 From
和 Into
特性,这些特性也可以应用于字面量
use decorum::R32;
fn f(x: R32) -> R32 {
x * 2.0
}
let y: R32 = 3.1459.into();
let z = f(2.7182.into());
let w: f32 = z.into();
原始类型
代理类型实现了 Eq
、Hash
和 Ord
,但有时使用此类类型可能不可行或不方便。可以使用特性来与原始浮点值一起用于排序、等价性和散列。
浮点特性 | 通用特性 |
---|---|
FloatEq |
Eq |
FloatHash |
Hash |
FloatOrd |
Ord |
这些特性使用了与代理类型相同的全序和等价规则。它们不仅为基本类型实现,也为切片实现了。
use decorum::cmp::FloatEq;
let x = 0.0f64 / 0.0f64; // `NaN`.
let y = f64::INFINITY + f64::NEG_INFINITY; // `NaN`.
assert!(x.float_eq(&y));
let xs = [1.0f64, f64::NAN, f64::INFINITY];
let ys = [1.0f64, f64::NAN, f64::INFINITY];
assert!(xs.float_eq(&ys));
依赖项
~130–365KB