我以为这个世界是可行的,但事实并非如此:
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 表示. (见下面的注释)
求负数的方法是:
- 取整数的二进制表示(包括数据类型的前导零,但 MSB 除外,它将用作符号位)。
- 接1's complement以上数量。
- 添加
1
1 的补码。 - 前缀a sign bit .
使用 500
例如,
- 取
500
的二进制表示:_000 0001 1111 0100
(_
是符号位的占位符)。 - 取其 1 的补码/倒数:
_111 1110 0000 1011
- 添加
1
1 的补码:_111 1110 0000 1011 + 1 = _111 1110 0000 1100
.这与2147483148
相同当您将符号位替换为零时,您获得了。 - 前缀
0
显示正数和1
对于负数:1111 1110 0000 1100
. (这与上面的2147483148
不同。您获得上述值的原因是因为您对 MSB 进行了核对)。
反转符号是一个类似的过程。如果您使用导致您看到的大值的 16 位或 32 位数字,您将获得前导数。 LSB 在每种情况下都应该相同。
注:1的补码表示的机器是有的,但是是少数。 2 的补码通常是首选,因为 0
具有相同的表示形式,即 -0
和 0
在 2 的补码中表示为全零。
关于c - 负数 : How can I change the sign bit in a signed int to a 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41712334/