我在这里有点困惑 - 当双打存储为不透明(二进制)字段时,双打的比较是否仍能正常工作?我面临的问题是双重包括符号的前导位(即正或负),当它们作为二进制数据存储时,我不确定它是否会被正确比较:
我想确保比较正常,因为我使用double作为key tuple (e.g. ) in LevelDB的一部分,我想保留正数和负数的数据位置。 LevelDB仅使用不透明字段作为键,但它允许用户指定他/她自己的比较器。但是,我只是想确保我没有指定比较器,除非我绝对需要:
// Three-way comparison function:
// if a < b: negative result
// if a > b: positive result
// else: zero result
inline int Compare(const unsigned char* a, const unsigned char* b) const
{
if (*(double*)a < *(double*)b) return -1;
if (*(double*)a > *(double*)b) return +1;
return 0;
}
答案 0 :(得分:3)
让我的评论成为答案。
有两件事可能出错:
如果其中一个(或两个)参数为NAN
,则比较将始终返回false。因此,即使二进制表示相同,NAN == NAN
也将始终为false。此外,它违反了比较传递性。
如果任一参数未正确对齐(因为它们是char指针),则可能会在不支持未对齐内存访问的计算机上遇到问题。对于那些可能会遇到性能影响的人。
因此,要解决此问题,您需要添加一个陷阱案例,如果任一参数变为NAN
,则会调用该案例。 (我不确定INF
的状态。)
由于需要此陷阱案例,您需要定义自己的比较运算符。
答案 1 :(得分:1)
是的,您必须指定自己的比较功能。这是因为双精度不一定存储为'big-endian'值。指数不会驻留在尾数之前的内存中,即使逻辑上它出现在尾数之前,当以big-endian格式写出值时。
当然,如果你在同一个数据库中的不同CPU架构之间共享东西,你最终可能会因为你把东西存储为二进制blob而得到奇怪的endian问题。
最后,即使你可以控制字节序,我仍然不相信它。例如,如果double未标准化,则在与二进制数据进行比较时,它可能无法与另一个double正确比较。
当然,在编写比较函数时,关注对齐和奇数值(如NAN和INF)的所有内容都非常重要。但是,至于你是否应该写一个,我不得不说这是一个非常好的主意。
答案 2 :(得分:1)
我假设您的数字格式符合IEEE 754标准。如果是这种情况,则简单的有符号整数比较将不起作用 - 如果两个数字均为负数,则比较结果将反转。所以你必须提供自己的比较器。