繁体   English   中英

双精度浮点比较

[英]Double precision floating-point comparison

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

在此处输入图片说明

我想确保比较能够正确进行,因为我在LevelDB中将double用作键元组(例如)的一部分,并且希望保留正负数的数据局部性。 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;
}

使我的评论成为答案。

有两件事可能出错:

  1. 如果一个(或两个)参数均为NAN ,则比较将始终返回false。 因此,即使二进制表示形式相同, NAN == NAN始终为false。 此外,它违反了比较传递性。

  2. 如果任何一个参数未正确对齐(由于它们是char指针),则在不支持未对齐内存访问的计算机上可能会遇到问题。 对于那些这样做的人,您可能会遇到性能下降的情况。

因此,要解决此问题,您将需要添加一个陷阱案例,如果其中一个参数原来是NAN ,则将调用该案例。 (我不确定INF的状态。)

由于需要这种陷阱情况,因此您需要定义自己的比较运算符。

是的,您必须指定自己的比较功能。 这是因为双精度不一定存储为“ big-endian”值。 即使从逻辑上讲,当以big-endian格式写出值时,指数也不会出现在尾数之前的内存中。

当然,如果要在同一个数据库中的不同CPU架构之间共享内容,则可能会因为存储内容为二进制Blob而最终遇到奇怪的字节序问题。

最后,即使您可以控制字节序,我仍然不会信任它。 例如,如果未对double进行归一化,则在将其作为二进制数据进行比较时,可能无法正确地将其与另一个double进行比较。

当然,在编写比较函数时,其他人所说的关于对齐和奇数(例如NAN和INF)的所有内容都非常重要。 但是,就您是否应该编写一个而言,我不得不说这将是一个非常好的主意。

我假设您的数字格式符合IEEE 754标准。 如果真是这样,那么简单的带符号整数比较将不起作用-如果两个数字均为负数,则比较的结果将相反。 因此,您必须提供自己的比较器。

暂无
暂无

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

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