简体   繁体   English

双精度浮点比较

[英]Double precision floating-point comparison

I'm a little confused here- would comparison of doubles still work correctly when they're stored as opaque (binary) fields? 我在这里有点困惑-当双精度数存储为不透明(二进制)字段时,双精度比较仍然可以正常工作吗? The problem I'm facing is the fact that the double includes a leading bit for the sign (ie positive or negative) and when they're stored as binary data I'm not sure it will be compared correctly: 我面临的问题是双精度数包含符号的前导位(即正数或负数),当它们存储为二进制数据时,我不确定是否可以正确比较它们:

在此处输入图片说明

I want to ensure that the comparison will work correctly, because I'm using a double as a part of a key tuple (eg ) in LevelDB and I want to preserve the data locality for positive and negative numbers. 我想确保比较能够正确进行,因为我在LevelDB中将double用作键元组(例如)的一部分,并且希望保留正负数的数据局部性。 LevelDB only uses opaque fields as keys, but it does allow the user to specify his/her own comparator. LevelDB仅使用不透明字段作为键,但它允许用户指定自己的比较器。 However, I just want to make sure that I don't specify a comparator unless I absolutely need to: 但是,我只想确保不要指定比较器,除非我绝对需要:

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

Making my comments an answer. 使我的评论成为答案。

There are two things that could go wrong: 有两件事可能出错:

  1. If either (or both) parameters is NAN , comparisons will always return false. 如果一个(或两个)参数均为NAN ,则比较将始终返回false。 So even if the binary representation is the same, NAN == NAN will always be false. 因此,即使二进制表示形式相同, NAN == NAN始终为false。 Furthermore, it violates comparison transitivity. 此外,它违反了比较传递性。

  2. If either parameter isn't properly aligned (since they are char pointers), you could run into problems on machines that don't support misaligned memory access. 如果任何一个参数未正确对齐(由于它们是char指针),则在不支持未对齐内存访问的计算机上可能会遇到问题。 And for those that do, you may encounter a performance hit. 对于那些这样做的人,您可能会遇到性能下降的情况。

So to get around this problem, you'll need to add a trap case that will be invoked if either parameter turns out to be NAN . 因此,要解决此问题,您将需要添加一个陷阱案例,如果其中一个参数原来是NAN ,则将调用该案例。 (I'm not sure on the status of INF .) (我不确定INF的状态。)

Because of the need for this trap case, you will need to define your own comparison operator. 由于需要这种陷阱情况,因此您需要定义自己的比较运算符。

Yes, you have to specify your own comparison function. 是的,您必须指定自己的比较功能。 This is because doubles are not necessarily stored as 'big-endian' values. 这是因为双精度不一定存储为“ big-endian”值。 The exponent will not reside in memory before the mantissa even though logically it appears before the mantissa when the value is written out in big-endian format. 即使从逻辑上讲,当以big-endian格式写出值时,指数也不会出现在尾数之前的内存中。

Of course, if you're sharing stuff between different CPU architectures in the same database, you may end up with weird endian problems anyway just because you stored stuff as binary blobs. 当然,如果要在同一个数据库中的不同CPU架构之间共享内容,则可能会因为存储内容为二进制Blob而最终遇到奇怪的字节序问题。

Lastly, even if you could control for endianness I would still not trust it. 最后,即使您可以控制字节序,我仍然不会信任它。 For example, if a double is not normalized it may not compare correctly to another double when compared as binary data. 例如,如果未对double进行归一化,则在将其作为二进制数据进行比较时,可能无法正确地将其与另一个double进行比较。

Of course, everything the other person said about alignment and odd values like NAN and INF are important to pay attention to when writing a comparison function. 当然,在编写比较函数时,其他人所说的关于对齐和奇数(例如NAN和INF)的所有内容都非常重要。 But, as far as whether you should write one at all, I would have to say that it would be a really good idea. 但是,就您是否应该编写一个而言,我不得不说这将是一个非常好的主意。

I assume that your number format conforms to the IEEE 754 standard. 我假设您的数字格式符合IEEE 754标准。 If that's the case, then a simple signed-integer comparison won't work -- if both numbers are negative, the result of the comparison is reversed. 如果真是这样,那么简单的带符号整数比较将不起作用-如果两个数字均为负数,则比较的结果将相反。 So you do have to provide your own comparator. 因此,您必须提供自己的比较器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM