这里我有点困惑--当双精度值被存储为不透明(二进制)字段时,它们仍然可以正确地工作吗?我面临的问题是,双精度数包含符号的前导位(即正或负),当它们存储为二进制数据时,我不确定它是否会被正确比较:

我希望确保比较工作正确,因为我使用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;
}发布于 2011-11-14 13:57:22
让我的评论成为答案。
有两件事可能会出错:
NAN,则比较将始终返回false。因此,即使二进制表示是相同的,NAN == NAN也将始终为false。此外,这违反了比较transitivity.因此,要解决此问题,您需要添加一个陷阱用例,如果其中一个参数为NAN,则将调用该陷阱用例。(我不确定INF的状态。)
由于这种陷阱情况的需要,您将需要定义自己的比较运算符。
发布于 2011-11-14 14:26:55
是的,您必须指定您自己的比较函数。这是因为doubles不一定存储为“big-endian”值。指数不会在尾数之前驻留在内存中,即使逻辑上它出现在尾数之前,当值以大端格式写出时也是如此。
当然,如果您在同一数据库中的不同CPU架构之间共享数据,您可能会因为将数据存储为二进制blob而出现奇怪的endian问题。
最后,即使您可以控制字节序,我仍然不会信任它。例如,如果一个double未标准化,则在作为二进制数据进行比较时,它可能无法正确地与另一个double进行比较。
当然,在编写比较函数时,其他人所说的关于对齐和奇异值(如NAN和INF )的所有内容都很重要。但是,至于你是否应该写一个,我不得不说这将是一个非常好的想法。
发布于 2011-11-14 15:40:57
我假设您的数字格式符合IEEE754标准。如果是这种情况,那么简单的带符号整数比较将不起作用--如果两个数字都是负数,则比较结果相反。所以你必须提供你自己的比较器。
https://stackoverflow.com/questions/8117663
复制相似问题