c++ - 使用位运算检测负整数

标签 c++ c binary

检查给定整数是否为负的一种方法可能是这样的:(使用位操作)

int num_bits = sizeof(int) * 8; //assuming 8 bits per byte!
int sign_bit = given_int & (1 << (num_bits-1)); //sign_bit is either 1 or 0
if ( sign_bit )
{
     cout << "given integer is negative"<<endl;
}
else
{
     cout << "given integer is positive"<<endl;
}

这个解决方案的问题是每字节的位数不能是 8,它可以是 9,10, 11 甚至 16 或 40 位每字节。字节不一定是8位!无论如何,这个问题可以通过编写轻松解决,

//CHAR_BIT is defined in limits.h
int num_bits = sizeof(int) * CHAR_BIT; //no assumption. 

现在看起来还不错。但真的如此吗?这个标准符合吗?如果负整数不表示为 2 的补码怎么办?如果它是二进制计数系统中的表示,不需要 负整数的最高有效位为 1 会怎么样?

我们能否编写出既可移植又符合标准的代码?


相关主题:
Size of Primitive data types
Why is a boolean 1 byte and not 1 bit of size?

最佳答案

注意:C 和 C++ 是不同的语言。他们各自的标准在某种程度上独立发展,并且对数字表示形式有不同的形式限制。


Can we write such code that will be both portable and standard conformant?

假设您需要一种识别和解释符号位的通用方法,我认为您问题的答案是否定的。

关于 C++:我不认为该标准对符号位的存在有明确的要求。即使每个实现都使用符号位,也不能保证它是代码假定的第一个(高阶)位。此外,该位的解释可能与您的假设相反(符号位的“1”值可能意味着该数字为正数)。

关于 C99:该语言确实需要符号位并要求 sign=1 表示负数(尽管它可能是“负零”)。但是,语言标准并未提供确定符号位位置的通用方法。

以下代码尝试以通用方式创建“sign_mask”,但不能绝对保证在 C99 或 C++ 中工作。失败的原因包括上面提到的那些,但最有趣的是,它可以调用“陷阱表示”(例如奇偶校验位错误)...

#ifdef __cplusplus
   #define INT_MAX std::numeric_limits<int>::max()
   #define UINT_MAX std::numeric_limits<unsigned int>::max() 
#endif

// assumes sign bit becomes high-order bit of unsigned
   int sign_mask = INT_MAX ^ UINT_MAX; 

// fallback in case unsigned type doesn't take advantage of the sign-bit
// This might invoke a "trap representation" on some platforms
   if (sign_mask==0) sign_mask = ~INT_MAX;

这篇维基百科文章讨论了用二进制表示有符号数的一些不同方式:Signed number representations

Here's an informative post about signed numbers in the C99 standard .

关于c++ - 使用位运算检测负整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4698311/

相关文章:

algorithm - 将小数转换为只有两位数的二进制 : 1 and 2

php - 有人可以向我解释一下 PHP 中的 pack() 函数吗?

c++ - 弹性代币订单

java - 正则表达式问题

c - goto 指令跳到变长数组前面

c - 你如何在 C 中定义一个不透明的结构数组?

c++ - 从 libexpect 获取输出

C++ 非类型模板参数 const char*

c++ - 错误 C2248 : 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'

asp.net - 我应该如何为 iOS 设计一个 ASP.NET 页面来上传二进制数据 block ?