gpt4 book ai didi

floating-point - 如何在处理负零时有效地比较两个浮点值的符号

转载 作者:行者123 更新时间:2023-12-04 03:05:50 24 4
gpt4 key购买 nike

给定两个浮点数,我正在寻找一种有效的方法来检查它们是否具有相同的符号,因为如果两个值中的任何一个为零(+0.0或-0.0),则应将它们视为具有相同的符号符号。

例如,

  • SameSign(1.0,2.0)应该返回true
  • SameSign(-1.0,-2.0)应该返回true
  • SameSign(-1.0,2.0)应该返回假
  • SameSign(0.0,1.0)应该返回true
  • SameSign(0.0,-1.0)应该返回true
  • SameSign(-0.0,1.0)应该返回true
  • SameSign(-0.0,-1.0)应该返回true

  • C++中 SameSign的一个幼稚但正确的实现将是:
    bool SameSign(float a, float b)
    {
    if (fabs(a) == 0.0f || fabs(b) == 0.0f)
    return true;

    return (a >= 0.0f) == (b >= 0.0f);
    }

    假设使用IEEE浮点模型,这是 SameSign的一种变体,可编译为无分支代码(至少在Visual C++ 2008中):
    bool SameSign(float a, float b)
    {
    int ia = binary_cast<int>(a);
    int ib = binary_cast<int>(b);

    int az = (ia & 0x7FFFFFFF) == 0;
    int bz = (ib & 0x7FFFFFFF) == 0;
    int ab = (ia ^ ib) >= 0;

    return (az | bz | ab) != 0;
    }
    binary_cast定义如下:
    template <typename Target, typename Source>
    inline Target binary_cast(Source s)
    {
    union
    {
    Source m_source;
    Target m_target;
    } u;
    u.m_source = s;
    return u.m_target;
    }

    我在寻找两件事:
  • 使用位技巧,FPU技巧甚至是SSE内部函数,可以更快,更有效地实现SameSign
  • SameSign有效扩展为三个值。

  • 编辑:

    我已经对 SameSign的三个变体(原始问题中描述的两个变体,以及斯蒂芬的变体)进行了一些性能测量。每个函数在101个浮点数组中的所有连续值对上运行200-400次,这些浮点数随机填充-1.0,-0.0,+ 0.0和+1.0。每次测量重复2000次,并保留最短时间(以消除所有缓存影响和系统导致的运行缓慢)。该代码是使用Visual C++ 2008 SP1编译的,具有最大程度的优化和SSE2代码生成功能。测量是在Core 2 Duo P8600 2.4 GHz上完成的。

    以下是计时,不计算从数组中获取输入值,调用函数并检索结果的开销(总计6-7个时钟信号):
  • 天真变体:15个滴答声
  • 位魔术变种:13个滴答声
  • Stephens的变体:6个滴答声
  • 最佳答案

    如果您不需要支持无限式,则可以使用:

    inline bool SameSign(float a, float b) {
    return a*b >= 0.0f;
    }

    在大多数现代硬件上,这实际上是非常快的,并且是完全可移植的。但是,它在(零,无穷大)情况下无法正常工作,因为零*无穷大是NaN,并且无论符号如何,比较都将返回false。当a和b都很小时,也会在某些硬件上引起异常停顿。

    关于floating-point - 如何在处理负零时有效地比较两个浮点值的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2922619/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com