2010-05-06 64 views
3

比较double号的最快方式是什么?比较两个双打号

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

除了“可移植性”的问题,有人能告诉我这个代码在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位开始,即使我只移位了一位?

其次,我可以检查double的第64位以检查它在MSVC++上的符号吗?

+0

哦,请不要回答'if((x <0 && y < 0) || (x > 0 && y> 0))puts(“same”); else puts(“different”);' – bobobobo 2010-05-06 15:17:47

+0

你有没有想过检查x和y乘积的符号? (x * y <0)? “不同”:“相同” – falconcreek 2010-05-06 15:27:12

+0

@falconcreek乘法运算出大数值溢出的风险 – corsiKa 2010-05-06 15:47:48

回答

2

在最低限度,有三个比较是-must-发生B的

  • 提取标志
  • 比较a和b平等
    1. 提取标志

      没有办法避免这三件事。

      你可以做一个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'ing他们。如果该位相同,则异或将为0(假) - 如果位不同,则异或将为1(真)。有一个很好的评论解释你在做什么,为什么,这是一个非常有效的方式来做到这一点。然而,你给出的“不使用这个”的例子并不是那么糟糕......它很容易阅读,这是你的代码中最重要的东西之一。有两条优化规则:

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

      不要牺牲可读性来优化已经非常快的东西,而且可能足够快。 :-)

    0
    ((((__int64*)(&z))*) & 0x8000000000000000) give you the sign 
    
    0

    double确实有一个符号位(最重要的位),但找到一个数字的符号比这个有点复杂。你想区分+0.0和-0.0吗?或+ NaN和-NaN之间?

    0

    在C++ 11中,我们分别给予std::signbit返回true如果,并false否则。

    给定两个双打,ab我们可以==!=比较自己的招牌:

    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::signbit支持doublefloatlong double,和所有的整数类型。它甚至可以处理NaN值。

    +0

    希望通过此答案减少StackOverflow上的一些错误! – AndyG 2017-08-13 00:16:08