首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双精度浮点比较

双精度浮点比较
EN

Stack Overflow用户
提问于 2011-11-14 13:24:30
回答 3查看 1K关注 0票数 8

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

我希望确保比较工作正确,因为我使用double作为key tuple (e.g. ) in LevelDB的一部分,并且希望保留正数和负数的数据局部性。LevelDB只使用不透明字段作为键,但它允许用户指定他/她自己的比较器。但是,我只想确保除非绝对需要,否则不指定比较器:

代码语言:javascript
复制
// 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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-14 13:57:22

让我的评论成为答案。

有两件事可能会出错:

  1. 如果其中一个(或两个)参数为NAN,则比较将始终返回false。因此,即使二进制表示是相同的,NAN == NAN也将始终为false。此外,这违反了比较transitivity.
  2. If任何一个参数没有正确对齐(因为它们是字符指针),你可能会在不支持未对齐内存访问的机器上遇到问题。对于那些这样做的人,你可能会遇到性能问题。

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

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

票数 3
EN

Stack Overflow用户

发布于 2011-11-14 14:26:55

是的,您必须指定您自己的比较函数。这是因为doubles不一定存储为“big-endian”值。指数不会在尾数之前驻留在内存中,即使逻辑上它出现在尾数之前,当值以大端格式写出时也是如此。

当然,如果您在同一数据库中的不同CPU架构之间共享数据,您可能会因为将数据存储为二进制blob而出现奇怪的endian问题。

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

当然,在编写比较函数时,其他人所说的关于对齐和奇异值(如NAN和INF )的所有内容都很重要。但是,至于你是否应该写一个,我不得不说这将是一个非常好的想法。

票数 1
EN

Stack Overflow用户

发布于 2011-11-14 15:40:57

我假设您的数字格式符合IEEE754标准。如果是这种情况,那么简单的带符号整数比较将不起作用--如果两个数字都是负数,则比较结果相反。所以你必须提供你自己的比较器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8117663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档