TL; DR IEEE754浮点值包括 NaN
是否满足LessThanComparable
?
具体来说,问题“Why does Release/Debug have a different result for std::min?”让我抬头LessThanComparable
:
该类型必须与<运算符和结果应该有标准 语义。
要求
如果
,则类型T满足LessThanComparable鉴于
- a,b和c,类型T或const T
的表达式以下表达式必须有效且具有指定的表达式 效果
与以下属性建立strict weak ordering关系 (...)
我在the standard中仔细检查了它,似乎它在那里基本相同,我查看了严格弱序的维基百科def 。
Some think包含NaN的IEEE浮点值集合不满足这个概念:任何一方与NaN的任何比较总是会产生错误,但是我一直在查看定义,NaN
是否存在strict weak ordering
维基百科提供的列表:
see below
似乎维基百科上定义的严格弱排序公理明确地提出了可能的incomparable
值:NaN似乎是一个很好的候选者?
另一方面,标准说:(25.5 / 4)
如果我们将
equiv(a, b)
定义为!comp(a, b) && !comp(b, a)
,那么 要求是comp和equiv都是传递关系:(4.1) -
comp(a, b) && comp(b, c)
隐含comp(a, c)
(4.2) -
equiv(a, b) && equiv(b, c)
隐含equiv(a, c)
根据这些定义,equiv(x, NaN)
始终为true
(因为!comp(a, NaN)==true
和 !comp(Nan, a)==true
:与Nan的比较产生错误,否定则产生真)
但显然(4.2)不满意,例如:
equiv(3.0, NaN) && equiv(NaN, 7.0) **does not** imply equiv(3.0, 7.0)
标准定义的不是严格的弱排序,或者 - 更可能确实 - 我在这里错过了什么?
答案 0 :(得分:8)
严格的弱排序要求存在强排序的等价类。 IEEE754不是这样。
问题不在于存在多个相互等效的NaN值,而是整个NaN类相对于实线无序。
违反(4.2)会导致您从维基百科引用的第四个项目符号中的测试也失败(让y
成为NaN)。
对于严格弱排序中允许的不可比性的示例,请考虑符号幅度整数。然后:
-4< -3< -2< -1< {-0,+ 0}< +1< +2< +3< 4
-0 < +0
和+0 < -0
都不是,所以排序很弱。但是由这些等价值形成的阶级对所有其他阶段都是有序的。
答案 1 :(得分:2)
IEEE754浮点值(包括NaN )不满足LessThanComparable。
如果您从维基百科中取得第4个项目符号并将无法比较的替换为equiv
,则其条件与标准中的相同。
这是一个很好的答案,基本上可以回答我所有的C ++问题。这样:
https://stackoverflow.com/a/8097097/321013
它甚至引用了std中与我在上面问题末尾所做的相同的段落:
如果我们将equiv(a,b)定义为!comp(a,b)&amp;&amp; !comp(b,a),然后是 要求是comp和equiv都是传递关系...... 等效(a,b)&amp;&amp; equiv(b,c)意味着equiv(a,c)
a = 0.0,b = NaN,c = 1.0,comp =
失败std::less<double>()
它也解决了一个有趣的问题。要求:
我一直认为有点奇怪的是标准 表示关键类型的要求,而不是表达 添加到容器的实际键值。我相信你可以 选择将其视为不保证
map<double, int>
具有此功能 如果实现支持NaN,则根本定义行为, 无论您是否实际向实例添加NaN。
答案 2 :(得分:1)
您似乎在说维基百科的定义允许使用NaN,但标准的定义却没有。我不认为你是对的。来自维基百科的定义:
对于S中的所有x,y,z,如果x与y无法比较(x
假设x为3.0,y为NaN,z为7.0。 x与y无法比较。 y与z无法比较。 x 与z无法比较。