为什么Rust没有通过f64和f32的Ord特性实现总排序?

Sha*_*mar 22 sorting floating-point partial-ordering rust

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

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

NaN在通用代码中是如此多的问题吗?

soc*_*soc 16

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

\n

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

\n

如果OrdPartialOrd不相关,那么从 IEEE754 规范 \xe2\x80\x93 实现 5.10 和 5.11 就很简单了,但因为它们不是 \xe2\x80\x93,Rust 必须选择一个,并且它选择了 5.11。

\n
\n

很容易想象一种不同的设计,例如Sortable提供 5.10 和Comparable5.11,并根据需要实现这两种设计。

\n

然后,用户可以写入Sortable是否需要全订单以及Comparable是否需要部分订单。

\n

  • @Rain 阅读规范。谢谢。 (3认同)

Pas*_*uoq 15

你的问题究竟是什么?您是在询问是否存在NaN,或者是否可以通过意外或自愿计算获得NaN?是的,它确实可以.当提供的订单不是总订单时,需要总订单的数据结构完全分解.你甚至不希望一个特殊的价值与它本身不同,因为它会打破结构的不变量,并意味着今后任何事情都可能发生.只要没有出现任何问题,NaN就不应该被认为是无害的,尽管已经在其他语言中尝试过.

IEEE 754的普通的比较操作符的定义<,<=......使他们非常有用的一般-如果不是当你需要一个总订单.特别是,很容易编写条件,以便将NaN输入发送到错误分支:

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

if (!(x >= MIN)) { // NaN makes this condition true
  error();
}
Run Code Online (Sandbox Code Playgroud)

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