比较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 :(得分:2)
至少有三次比较 - 必须发生
没有办法避免这三件事。
你可以做一个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。如果该位相同,则xor将为0(假) - 如果位不同,则xor将为1(真)。通过一个很好的评论来解释你正在做什么以及为什么,这是一个非常有效的方法。
但是:你给出的“不要使用它”的例子并不是那么糟糕......它很容易阅读,这是你的代码中最重要的事情之一。优化有两个规则:
不要牺牲可读性来优化已经非常快速的东西,并且可能足够快。 : - )
答案 1 :(得分:0)
((((__int64*)(&z))*) & 0x8000000000000000) give you the sign
答案 2 :(得分:0)
double
确实有一个符号位(最重要的位),但找到一个数字的符号比这复杂一点。你想区分+0.0和-0.0吗?或者在+ NaN和-NaN之间?
答案 3 :(得分:0)
在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";
}
std::signbit
支持double
,float
,long double
和所有整数类型。它甚至可以处理NaN
值。