IEE 754标准C++ 11中的总订单

Bas*_*tch 10 ieee-754 c++11

根据IEEE浮点 wikipage(在IEEE 754上),双精度浮点有一个总顺序(即在具有IEEE-754浮点数的C++ 11实现上,如Linux/x86-64上的gcc 4.8).

当然,operator <on double通常提供一个总订单,但已知NaN是例外(众所周知的民间传说x != x是一种测试方法,如果被x宣布为double x;NaN).

我问的原因是我想要ag std::set<double>(实际上是一组类似JSON的或者类似于Python的值)并且我希望该集合具有一些规范表示(我实际关注的是发出可移植的JSON -same)数据,按照相同的顺序排列,在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;
}
Run Code Online (Sandbox Code Playgroud)

实际上,我确实知道它不是一个真正的(数学上说)总顺序(因为例如逐位不同的NaN都是相等的),但我希望它在几个常见的体系结构上具有相同(或非常接近)的行为.

有任何意见或建议吗?

(也许我不应该那么在乎;我故意不关心信号NaNs)

总的动机是我正在编写一些动态类型的解释器,它以JSON表示法保持其整个内存状态,我想确保架构之间的持久状态是稳定的,换句话说,如果我加载JSON状态并转储它,它对于几种架构(特别是x86-64,ia-32,ARM 32位......)都是幂等的.

Pas*_*uoq 8

我会用:

int totalcompare(double x, double y) {
    int64_t rx, ry;

    memcpy(&rx, &x, sizeof rx);
    memcpy(&ry, &y, sizeof ry);

    if (rx == ry) return 0;

    if (rx < 0) rx ^= INT64_MAX;
    if (ry < 0) ry ^= INT64_MAX;

    if (rx < ry) return -1; else return 1;
 }
Run Code Online (Sandbox Code Playgroud)

这使得0.0-0.0比较不相等,而if (x==y) return 0;在你的版本中它们比较相等,这意味着你的版本只是一个预订.NaN值高于其余值,不同的NaN比较不同.<=对于上述关系,所有可比较的值应该是相同的顺序.

注意:上面的函数是C.我不懂C++.

  • @chux-ReinstateMonica 我不了解 C,但联合类型双关在 C++ 中是显式的 UB。你唯一的选择是 `memcpy` 或 C++20 的 `bit_cast` IIRC (2认同)