无符号整数的位移,为什么为负
bit shift for unsigned int, why negative?
代码:
unsigned int i = 1<<31;
printf("%dn", i);
为什么输出是-2147483648
,负值?
更新的问题:
#include <stdio.h>
int main(int argc, char * argv[]) {
int i = 1<<31;
unsigned int j = 1<<31;
printf("%u, %un", i, j);
printf("%d, %dn", i, j);
return 0;
}
以上打印:
2147483648, 2147483648
-2147483648, -2147483648
那么,这是否意味着有符号 int 和无符号 int 具有相同的位值,区别在于您在将第 31 位转换为数字值时如何处理它?
>%d
打印unsigned int i
的int
版本。尝试%u
unsigned int
。
printf("%un", i);
int main(){
printf("%d, %u",-1,-1);
return 0;
}
Output: -1, 4294967295
整数的存储方式以及如何将其从无符号转换为有符号,反之亦然将对您有所帮助。遵循这个。
为了回答您的更新问题,系统如何表示它们,即在 2 的补码中(如上述情况 -1 =2's complement of 1 = 4294967295
.
%u
' 表示unsigned int
printf("%un", i);
............
对更新问题的回答:任何位序列都可以解释为有符号或无符号值。
printf("%dn", i);
调用 UB。 i
unsigned int
,您尝试将其打印为 signed int
.编写1 << 31
而不是1U << 31
也是未定义的。
将其打印为:
printf("%un", i);
或
printf("%Xn", i);
关于您更新的问题,它也出于同样的原因调用 UB(如果您使用"1U"而不是 1
,那么因为int
是用超出范围值的1U << 31
初始化的。如果使用超出范围的值初始化unsigned
,则会出现模算术并分配余数。对于signed
行为是未定义的。
了解平台上的行为
在您的平台上,int 显示为 4 个字节。当你写一些类似 1 << 31
的东西时,它会转换为0x80000000
机器上的比特模式。
现在,当您尝试将此模式打印为签名时,它会在 2s 完成系统中打印有符号解释,即 -231(AKA INT_MIN(。当您将其打印为无符号时,您会得到预期的 231 作为输出。
知识
1. 使用1U << 31
代替1 << 31
2. 始终在 printf 中使用正确的打印说明符。
3. 将正确的参数类型传递给可变参数函数。
4. 发生隐式类型转换(无符号 -> 有符号、宽类型 ->窄类型(时要小心。如果可能,请完全避免此类铸件。
尝试
printf("%un", i);
通过使用%d
说明符,printf 期望参数为int
,并且它类型转换为int
。因此,请使用%u
进行unsigned int
。
您不是在unsigned
上而是在signed int
上执行移位操作。
-
1
signed
. - 然后,移位操作移入符号位该
signed
(假设int
是 32 位宽(,这已经是未定义的行为 - 然后,您将编译器认为他想要的任何值分配给
unsigned
。 - 然后,将
unsigned
打印为已签名的,同样没有定义的行为。
%u
用于无符号的int。
%d
用于已签名的 int。
在您的程序输出中:
2147483648, 2147483648 (output for unsigned int)
-2147483648, -2147483648 (output for signed int )
- 如何打印boost多精度128位无符号整数
- C++模板函数,用于比较任何无符号整数和有符号整数
- 在线程中读取无符号整数时,c++ 位是否以原子方式切换?
- Constexpr 可变参数模板,用于对无符号整数进行重新排序
- 为什么 Clang 和 GCC 中两个无符号整数之和的结果类型不同
- 从 std::string 转换为 const 无符号整数
- 迭代器和无符号整数的重载 + 运算符
- C++,概念不适用于无符号整数作为结果类型?
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- 原子式清除无符号整数的最低非零位
- 计算机使用什么方法添加无符号整数
- boost::任何带有结构体和无符号整数
- 添加有符号和无符号整数
- 如何安全地比较两个无符号整数计数器?
- 计算 (64 位无符号整数) * (64 位无符号整数) 的商除以 2^64
- 如何将 32 位无符号整数分配给包含 32 位的位字段
- 为什么C++标准指定有符号整数在具有混合符号的二进制操作中强制转换为无符号整数
- 为什么尽管变量是无符号整数,但该程序仍以 -25 给出输出
- 无符号整数的位移,为什么为负
- 为什么无符号整数容易出错