"a <= b" 和 "not ( b > a)"
今天在看《LUA程序设计(第2版)》时候,发现了一个比较有意思的问题。
在 13.2 节 关系类的元方法 中,作者解释道为什么要同时提供 小于 和 小于等于 两个关系运算符的实现:
在 Lua 4.0 之前,所有顺序操作符(order operators)都被转化为一种操作符(小于),例如,a <= b 转化为 not (b < a)。不过,这种转化遇到“部分有序(partial order)”就会发生错误。所谓“部分有序”是指,对于一种类型而言,并不是所有的值都能排序的。例如,大多数计算机中的浮点数就不是完全可以排序的。因为存在着一种叫 “Not a Number (NaN)”的值。 IEEE 754 是一份当前所有浮点数硬件都采用的事实标准,其中将 NaN 视为一种未定义的值,例如 0/0 的结果就是 NaN。标准规定了任何涉及 NaN 的比较都应返回 false(假)。这意味着 NaN <= x 永远为假,但是 x < NaN 也为假。因此,前面提到的将 a <= b 转化为 not ( b < a ) 就不合法了。
就是说 关系运算符的结果并非都是真的表示两个运算数是可以比较的,例如 在 IEEE 754 标准中提到,所有涉及 NaN 的浮点数关系比较全部应返回 false,也就是说 NaN <= x 为 false,NaN > x 也为 false,所以 a <= b 和 not ( b > a) 并非完全等价。
另外一段叙述是针对扩展使用的
在上面的集合示例中,也存在着类似的问题。在集合操作中 <= 通常表示集合间的包含关系: a <= b 通常意味着 a 是 b 的一个子集。根据这样的表示,仍有可能得到 a <= b 和 b < a 同时为假的情况。因此需要分别为 __le(小于等于)和 __lt(小于)提供实现
这里举例,a、b 两个集合交集为空,并集不为空,则 a <= b 为假,而 b > a 也为假。