使用按位运算符检查数字是正数还是负数

Ani*_* Er 31 c c++ algorithm bit-manipulation

我可以使用按位运算符检查数字是否为奇数/偶数.我可以在不使用任何条件语句/运算符(如if/ternary等)的情况下检查数字是正数还是零/负数.

可以使用按位运算符和C或C++中的一些技巧来完成相同的操作吗?

Kon*_*lph 27

我可以在不使用任何条件语句/运算符(如if/ternary等)的情况下检查数字是正数还是零/负数.

当然:

bool is_positive = number > 0;
bool is_negative = number < 0;
bool is_zero = number == 0;
Run Code Online (Sandbox Code Playgroud)

  • 实际上这是唯一独立于平台的方式.而且,它比****平台上的按位检查更有效. (8认同)
  • @KonradRudolph是的,但值得指出今天发现这个讨论的人. (2认同)

Jim*_*hel 16

如果高位设置在有符号整数(字节,长整数等,但不是浮点数)上,则该数字为负数.

int x = -2300;  // assuming a 32-bit int

if ((x & 0x80000000) != 0)
{
    // number is negative
}
Run Code Online (Sandbox Code Playgroud)

添加:

你说你不想使用任何条件.我想你可以这样做:

int isNegative = (x & 0x80000000);
Run Code Online (Sandbox Code Playgroud)

稍后您可以使用它进行测试if (isNegative).

  • 现在的浮点数往往采用IEEE格式,它具有明确的符号位. (5认同)

gro*_*kus 11

有关Bit Twiddling Hacks页面的详细讨论.

int v;      // we want to find the sign of v
int sign;   // the result goes here 

// CHAR_BIT is the number of bits per byte (normally 8).
sign = -(v < 0);  // if v < 0 then -1, else 0. 
// or, to avoid branching on CPUs with flag registers (IA32):
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
// or, for one less instruction (but not portable):
sign = v >> (sizeof(int) * CHAR_BIT - 1); 

// The last expression above evaluates to sign = v >> 31 for 32-bit integers.
// This is one operation faster than the obvious way, sign = -(v < 0). This
// trick works because when signed integers are shifted right, the value of the
// far left bit is copied to the other bits. The far left bit is 1 when the value
// is negative and 0 otherwise; all 1 bits gives -1. Unfortunately, this behavior
// is architecture-specific.

// Alternatively, if you prefer the result be either -1 or +1, then use:

sign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1));  // if v < 0 then -1, else +1

// On the other hand, if you prefer the result be either -1, 0, or +1, then use:

sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
// Or, for more speed but less portability:
sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1));  // -1, 0, or +1
// Or, for portability, brevity, and (perhaps) speed:
sign = (v > 0) - (v < 0); // -1, 0, or +1

// If instead you want to know if something is non-negative, resulting in +1
// or else 0, then use:

sign = 1 ^ ((unsigned int)v >> (sizeof(int) * CHAR_BIT - 1)); // if v < 0 then 0, else 1

// Caveat: On March 7, 2003, Angus Duggan pointed out that the 1989 ANSI C
// specification leaves the result of signed right-shift implementation-defined,
// so on some systems this hack might not work. For greater portability, Toby
// Speight suggested on September 28, 2005 that CHAR_BIT be used here and
// throughout rather than assuming bytes were 8 bits long. Angus recommended
// the more portable versions above, involving casting on March 4, 2006.
// Rohit Garg suggested the version for non-negative integers on September 12, 2009. 
Run Code Online (Sandbox Code Playgroud)


Wil*_*iss 11

或者,您可以使用signbit()并完成工作.

我假设在幕后,math.h实现是一个有效的按位检查(可能解决你的原始目标).

参考:http://en.cppreference.com/w/cpp/numeric/math/signbit