c - 负数 : How can I change the sign bit in a signed int to a 0?

标签 c bit-manipulation

我以为这个世界是可行的,但事实并非如此:

int a = -500;
a = a << 1;
a = (unsigned int)a >> 1;
//printf("%d",a) gives me "2147483148"

我的想法是左移会删除最左边的符号位,因此将其右移为 unsigned int 将保证它是逻辑移位而不是算术移位。为什么这是不正确的?

还有:

int a = -500;
a = a << 1;
//printf("%d",a) gives me "-1000"

最佳答案

TL;DR:最简单的方法是使用 abs来自 <stdlib.h> 的函数.其余答案涉及负数在计算机上的表示。

负整数(几乎总是)用 2's complement form 表示. (见下面的注释)

求负数的方法是:

  1. 取整数的二进制表示(包括数据类型的前导零,但 MSB 除外,它将用作符号位)。
  2. 1's complement以上数量。
  3. 添加1 1 的补码。
  4. 前缀a sign bit .

使用 500例如,

  1. 500的二进制表示: _000 0001 1111 0100 (_ 是符号位的占位符)。
  2. 取其 1 的补码/倒数:_111 1110 0000 1011
  3. 添加1 1 的补码:_111 1110 0000 1011 + 1 = _111 1110 0000 1100 .这与 2147483148 相同当您将符号位替换为零时,您获得了。
  4. 前缀 0显示正数和 1对于负数:1111 1110 0000 1100 . (这与上面的 2147483148 不同。您获得上述值的原因是因为您对 MSB 进行了核对)。

反转符号是一个类似的过程。如果您使用导致您看到的大值的 16 位或 32 位数字,您将获得前导数。 LSB 在每种情况下都应该相同。

注:1的补码表示的机器是有的,但是是少数。 2 的补码通常是首选,因为 0具有相同的表示形式,即 -00在 2 的补码中表示为全零。

关于c - 负数 : How can I change the sign bit in a signed int to a 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41712334/

相关文章:

c++ - 关于枚举和按位运算

组合三个位以获得单个整数值

c - 在文件中设置 eof 指示器

sql-server - SQL Server - 使用按位运算符查找最高优先级的项目

c - 管道 & 执行 & C

C:从函数返回字符串

c# - 将移位后的数字转换回其原始索引

c - 这个 "bit set"在 C 中是如何工作的?

c - 访问结构数组中结构的成员,该结构是不同结构数组的成员

c - 如何使用 openssl 库生成 key 对并将其用于 C 中的加密/解密?