[英]Why does Rust not implement total ordering via the Ord trait for f64 and f32?
虽然 Rust 中的所有整数类型都实现了强调全序的Ord
,但浮点类型只实现PartialOrd
。 这意味着可能存在无法比较的浮点值。 这似乎很难消化,因为浮点数可以被认为是对实数的近似,而实数恰好是一个完全有序的集合。 即使加上正无穷和负无穷,也能保持实数集完全有序。 为什么在 Rust 中有这个奇怪的选择?
此限制意味着通用排序/搜索算法只能假设对数字进行部分排序。 IEEE 754 标准似乎提供了一个总排序谓词。
泛型代码中的 NaN 有这么大的问题吗?
你的问题究竟是什么? 您是在询问是否存在NaN,或者是否可以通过意外或自愿计算获得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的任何人从库中选择它,甚至自己定义它。
它不能,因为 Rust 的核心设计错误是让Ord
成为PartialOrd
的子类型。
这意味着尽管浮点值具有总顺序,但该层次结构中只能有一个实现; 并且该实现使用比较谓词(仅是部分顺序),而不是全顺序谓词(这是全顺序(因此也是部分顺序))。
如果Ord
和PartialOrd
不相关,那么实现 IEEE754 规范中的 5.10 和 5.11 将是微不足道的——但因为它们不是——Rust 必须选择一个,它选择了 5.11。
很容易想象一种不同的设计,例如, Sortable
提供 5.10, Comparable
提供 5.11,并且类型在适当的时候实现了这两者。
然后,如果用户需要全序,则可以写Sortable
,如果需要偏序,则可以写Comparable
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.