Sha*_*mar 22 sorting floating-point partial-ordering rust
虽然Rust实现的所有整数类型Ord都强调总排序,但浮点类型只能实现PartialOrd.这意味着可能存在无法比较的浮点值.这似乎很难消化,因为浮点数可以被认为是实数的近似值,恰好是一个完全有序的集合.即使增加正负无穷大也能保持实数的整数排序.为什么这个奇怪的选择在Rust?
此限制意味着通用排序/搜索算法只能假设数字的部分排序.IEEE 754标准似乎提供了总排序谓词.
NaN在通用代码中是如此多的问题吗?
soc*_*soc 16
它不能,因为 Rust 的核心设计错误是Ord创建 PartialOrd.
这意味着尽管浮点值具有总顺序,但该层次结构内只能有一个实现;并且该实现使用比较谓词(这只是偏序),而不是全序谓词(这是全序(因此也是偏序))。
\n如果Ord和PartialOrd不相关,那么从 IEEE754 规范 \xe2\x80\x93 实现 5.10 和 5.11 就很简单了,但因为它们不是 \xe2\x80\x93,Rust 必须选择一个,并且它选择了 5.11。
很容易想象一种不同的设计,例如Sortable提供 5.10 和Comparable5.11,并根据需要实现这两种设计。
然后,用户可以写入Sortable是否需要全订单以及Comparable是否需要部分订单。
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的任何人从库中选择它,甚至自己定义它.