IEE 754总订单标准C ++ 11 [英] IEE 754 total order in standard C++11

查看:109
本文介绍了IEE 754总订单标准C ++ 11的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 IEEE浮点 wikipage(在IEEE 754上),有一个总订单(即 C ++ 11 实现具有IEEE-754浮点,如Linux / x86-64上的gcc 4.8)。

According to the IEEE floating point wikipage (on IEEE 754), there is a total order on double-precision floating points (i.e. on C++11 implementations having IEEE-754 floats, like gcc 4.8 on Linux / x86-64).

当然, code>运算符< 在 double 通常提供一个总订单,但NaN被称为异常(它是众所周知的民俗 x!= x 是一种测试 x ,声明为 double x; 是一个NaN)。

Of course, operator < on double is often providing a total order, but NaN are known to be exceptions (it is well known folklore that x != x is a way of testing if x, declared as double x; is a NaN).

我问的原因是我想要有 std :: set< double> (实际上,一组类似JSON或Python的值),我想集合有一些规范的表示关注的是发出可移植的JSON-数据,以相同的顺序排序,在Linux / x86-64上,例如在Linux / ARM上,即使在像NaN这样的奇怪的情况下)。

The reason I am asking is that I want to have a.g. std::set<double> (actually, a set of JSON-like -or Python like- values) and I would like the set to have some canonical representation (my practical concern is to emit portable JSON -same data, ordered in the same order, both on Linux/x86-64 and e.g. on Linux/ARM, even in weird cases like NaN).

我找不到任何简单的方法来获得总订单。我编码

I cannot find any simple way to get that total order. I coded

// 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;
}

其实,我知道这不是一个真正order
(因为例如bit-wise不同的NaN都是相等的),但我希望它在几个常见的架构上具有相同的
(或非常接近)的行为。

Actually, I do know that it is not a really (mathematically speaking) total order (since e.g. bit-wise different NaN are all equal), but I am hoping it has the same (or a very close) behavior on several common architectures.

有任何意见或建议吗?

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

(perhaps I should not care that much; and I deliberately don't care about signaling NaNs)

总的动机是我编码一些动态类型解释器,它以JSON格式保持其整个内存状态,并且我想确保持久化状态在架构之间是稳定的,换句话说,如果我加载JSON状态并转储它,它对于几个架构(特别是所有的x86

The overall motivation is that I am coding some dynamically typed interpreter which persists its entire memory state in JSON notation, and I want to be sure that the persistent state is stable between architectures, in other words if I load the JSON state and dump it, it stays idempotent for several architectures (notably all of x86-64, ia-32, ARM 32 bits...).

推荐答案

我会用:

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 = (~rx) | INT64_MIN;
    if (ry < 0)
      ry = (~ry) | INT64_MIN;

    if (rx < ry) return -1; else return 1;
 }

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

This makes 0.0 and -0.0 compare unequal, whereas if (x==y) return 0; in your version makes them compare equal, meaning that your version is only a preorder. NaN values are above the rest and different NaNs compare different. All values comparable for <= should be in the same order for the above relation.

注意:函数是C.我不知道C ++。

Note: the above function is C. I do not know C++.

这篇关于IEE 754总订单标准C ++ 11的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆