36

虽然 Rust 中的所有整数类型都实现Ord了强调全序,但浮点类型只实现了PartialOrd. 这意味着可能存在无法比较的浮点值。这似乎很难理解,因为浮点数可以被认为是对实数的近似,而实数恰好是一个完全有序的集合。即使加上正无穷和负无穷,也能保持实数集完全有序。为什么在 Rust 中有这个奇怪的选择?

此限制意味着通用排序/搜索算法只能假设对数字进行部分排序。IEEE 754 标准似乎提供了一个总排序谓词

泛型代码中的 NaN 有这么大的问题吗?

4

2 回答 2

20

你的问题是什么,确切地说?您是在问 NaN 是否存在,或者是否可以作为偶然或自愿计算的结果获得?是的,它确实可以。当提供的顺序不是全顺序时,需要键的全顺序的那种数据结构会完全崩溃。您甚至不希望一个异常值与其自身不同,因为它会破坏结构的不变量并意味着此后任何事情都可能发生。只要没有显示出问题,NaN 就不应被认为是无害的,尽管已经在其他语言中尝试过

IEEE 754 对普通比较运算符<, <=, ... 的定义使它们在一般情况下非常有用——如果不是在您需要全序时。特别是,很容易编写条件,以便将 NaN 输入发送到错误分支:

if (!(x <= MAX)) { // NaN makes this condition true
  error();
}

if (!(x >= MIN)) { // NaN makes this condition true
  error();
}

因为<<=非常有用,它们是现代处理器中作为单个快速指令实现的操作——来自 IEEE 754 的 totalOrder 谓词通常不在硬件中实现。编程语言将快速指令映射到语言中的构造,让任何特别需要 totalOrder 的人从库中挑选它,甚至自己定义它。

于 2014-10-21T15:14:29.867 回答
5

它不能,因为 Rust 的核心设计错误是Ord创建 PartialOrd.

这意味着尽管浮点值具有总顺序,但该层次结构中只能有一个实现;并且该实现使用比较谓词(仅是部分顺序),而不是全顺序谓词(这是全顺序(因此也是部分顺序))。

如果Ord并且PartialOrd不相关,那么实现 IEEE754 规范中的 5.10 和 5.11 将是微不足道的——但因为它们不是——Rust 必须选择一个,它选择了 5.11。


很容易想象一种不同的设计,例如Sortable提供 5.10 和Comparable提供 5.11,并根据需要实现这两者的类型。

然后,用户可以写Sortable她是否需要总订单,Comparable如果她需要部分订单。

于 2021-09-09T12:10:33.393 回答