【发布时间】:2013-11-20 13:33:02
【问题描述】:
根据IEEE floating point wikipage(在 IEEE 754 上),在双精度浮点上有一个 total order(即在具有 IEEE-754 浮点数的 C++11 实现上,如 Linux / x86-64 上的 gcc 4.8 )。
当然,double 上的operator < 经常提供总顺序,但 NaN 被认为是例外(众所周知,x != x 是一种测试 x 是否声明为 @ 987654329@ 是一个 NaN)。
我问的原因是我想拥有 a.g. std::set<double>(实际上是一组类似 JSON 或类似 Python 的值)并且我希望该集合具有一些规范表示(我实际关心的是发出可移植的 JSON 相同的数据,以相同的顺序排序,两者在 Linux/x86-64 和例如 Linux/ARM 上,即使在像 NaN 这样的奇怪情况下)。
我找不到任何简单的方法来获得总订单。我编码了
// a totally ordering function,
// return -1 for less-than, 0 for equal, +1 for greater
int mydoublecompare(double x, double y) {
if (x==y) return 0;
else if (x<y) return -1;
else if (x>y) return 1;
int kx = std::fpclassify(x);
int ky = std::fpclassify(y);
if (kx == FP_INFINITE) return (x>0)?1:-1;
if (ky == FP_INFINITE) return (y>0)?-1:1;
if (kx == FP_NAN && ky == FP_NAN) return 0;
return (kx==ky)?0:(kx<ky)?-1:1;
}
实际上,我知道这不是一个真正的(从数学上讲)全序 (因为例如按位不同的 NaN 都是相等的),但我希望它具有相同的 (或非常接近的)几种常见架构上的行为。
有什么建议或建议吗?
(也许我不应该那么在意;而且我故意不关心signaling NaNs)
总体动机是我正在编写一些动态类型解释器,它以 JSON 表示法保持其整个内存状态,并且我想确保持久状态在架构之间是稳定的,换句话说,如果我加载JSON 状态并转储它,它对于多种架构(尤其是所有 x86-64、ia-32、ARM 32 位......)保持幂等。
【问题讨论】:
-
set不是只需要 SWO,而不是总订单吗? -
对不起,SWO 是什么意思?很快就找不到了! (一些弱命令)?
-
您不需要特别处理无穷大,它们由内置比较服务。您确实需要处理正零和负零,因为它们比较相等但可以区分。
-
+-0.0 可能比不同风格的 NaN 更重要。
-0.0 == 0.0.