代码之家  ›  专栏  ›  技术社区  ›  bobobobo

比较两个双精度数的符号

  •  3
  • bobobobo  · 技术社区  · 14 年前

    比较登录的最快方法是什么? double ?

    我知道A 双重的 有一个“符号位”,但我不确定我在它的二进制表示中“寻找它”的方式是否是一个好主意。

    除了“可移植性”问题,有人能告诉我MSVC++中的代码是怎么回事吗?

    #include <stdio.h>
    
    int main()
    {
      double z = 5.0 ;
    
      __int64 bitSign ;
    
      __int64 *ptr ;
    
      ptr = (__int64*)&z ;
    
      for( __int64 sh = 0 ; sh < 65 ; sh++ )
      {
        bitSign = 1L << sh ; // Weird.  it doesn't do 1.
        printf( "Bit# %d (%llx):  %lld\n",
          sh, bitSign, ( (*ptr) & bitSign) ) ;
      }
    
    }
    

    首先,为什么从32位开始,即使我只移动了一位?

    第二,我可以检查第64位 双重的 要检查它在MSVC++上的签名吗?

    4 回复  |  直到 7 年前
        1
  •  2
  •   corsiKa    14 年前

    至少,必须进行三次比较

    1. 提取符号A
    2. 提取B的符号
    3. 比较A和B是否相等

    没有办法避免这三件事。

    你可以做一个 and ,你可以做一个 less than 你可能会找到一种很酷/聪明/狡猾的方法来用另一种方法来做,这并不重要。但你仍然需要这三个基本操作。也没有必要过分复杂化。如果你想找点东西贴在一条线上,你可以这样做:

    __int64 mask = 0x8000000000000000; // i think that's the right amount of 0's :-)
    if( (x&mask) ^ (y&mask) ) 
      puts("different");
    else
      puts("same");
    

    在这里,我提取钻头并将其取出。如果位相同,XOR将为0(假)-如果位不同,XOR将为1(真)。有了一个很好的评论来解释你在做什么和为什么,这是一个非常有效的方法。

    但是:你举的“不要用这个”的例子并没有那么糟糕…很容易阅读,这是代码中最重要的内容之一。优化有两条规则:

    1. 别这样。
    2. (仅限专家)暂时不要这样做。

    不要牺牲可读性来优化那些已经相当快,并且可能足够快的东西。-)

        2
  •  0
  •   Andrey    14 年前
    ((((__int64*)(&z))*) & 0x8000000000000000) give you the sign
    
        3
  •  0
  •   dan04    14 年前

    double 确实有一个符号位(最重要的位),但是找到一个数字的符号要比这个复杂一点。是否要区分+0.0和-0.0?还是在+nan和-nan之间?

        4
  •  0
  •   AndyG    7 年前

    在C++ 11中,我们给出了 std::signbit 它会回来的 true 如果 消极的 false 否则。

    给两个双打, a b 我们可以比较他们的体征 == != :

    void classify(double _lhs, double _rhs)
    {
        std::cout << _lhs << " and " << _rhs;
        if (std::signbit(_lhs) == std::signbit(_rhs))
            std::cout << " have the same sign\n";
        else
            std::cout << " have different signs\n";
    }
    

    Live Demo


    STD::符号 支架 double , float , long double 以及所有整型。它甚至可以处理 NaN 价值观。