比较两个双精度浮点数的符号

3

如何快速比较双精度浮点数的符号?

我知道双精度浮点数有一个“符号位”,但我不确定在其二进制表示中“查找它”的方式是否可行。

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

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


请勿回答 if( (x < 0 && y < 0) || (x > 0 && y > 0) ) puts( "same" ) ; else puts ("different") ; - bobobobo
你有没有想过检查 x 和 y 的乘积的符号? ( x * y < 0 ) ? "不同" : "相同" - falconcreek
@falconcreek 在大值的情况下,进行乘法运算存在溢出的风险。 - corsiKa
4个回答

2

在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";
}

实时演示


std::signbit 支持 doublefloatlong double 和所有整数类型。它甚至可以处理 NaN 值。


2

至少需要进行三个比较:

  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");

在这里,我提取比特并进行异或操作。如果位相同,则异或将为0(假) - 如果位不同,则异或将为1(真)。通过良好的注释解释您正在做什么以及为什么,这是一种完全有效的方法。

然而:您提供的“不要使用此”示例实际上并不那么糟糕......它很容易阅读,这是您的代码中最重要的事情之一。优化有两个规则:

  1. 不要优化。
  2. (仅限专家)暂时不要优化。

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


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

0

double类型确实有一个符号位(最高有效位),但是要找到一个数字的符号比这更加复杂。您想区分+0.0和-0.0吗?还是+NaN和-NaN之间的区别?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接