如果我有int temp =(1 < < 31)>> 31。温度怎么会变成-1? 我该如何解决这个问题? 谢谢按位移问题
按位移问题
回答
默认情况下,Ints是带符号的,这通常意味着高位被保留以指示整数是否为负值。请查阅Two's complement以了解其工作原理的解释。
这里的结果是:
[[email protected]:~]% cat test.c
#include <stdint.h>
#include <stdio.h>
int main(int argc, char **argv[]) {
uint32_t uint;
int32_t sint;
int64_t slong;
uint = (((uint32_t)1)<<31) >> 31;
sint = (1<<31) >> 31;
slong = (1L << 31) >> 31;
printf("signed 32 = %d, unsigned 32 = %u, signed 64 = %ld\n", sint, uint, slong);
}
[[email protected]:~]% ./test
signed 32 = -1, unsigned 32 = 1, signed 64 = 1
注意如何可以通过使用一个“无符号” INT(允许使用所有32位的)来避免这种问题,或者去一个更大的类型,你不要没有溢出。
int被签名。
什么'问题' - 你想做什么?
int i = (1<<31); // i = -2147483648
i>>31; // i = -1
unsigned int i = (1<<31); // i = 2147483648
i>>31; // i = 1
PS ch是一个不错的命令行“C” intepreter窗户,让你尝试这种东西无需编译,它也给你一个UNIX命令shell。请参阅http://www.drdobbs.com/184402054
对于您的情况,表达式中的1
是一种带符号的类型 - 所以当您将它升档31时,其符号会发生变化。然后降档导致符号位被复制,并且最终得到一个0xffffffff
的位模式。
你能解决这个问题是这样的:
int temp = (1UL << 31) >> 31;
GCC发出警告这样那样的错误,如果你已经-Wall
开启。
我检查了符号扩展的描述,但是我看不到它与OP观察到的现象有何关系。问题是,在他的实现中,右移是算术移位,int是有符号的,长32位。 http://en.wikipedia.org/wiki/Arithmetic_shift – 2010-07-08 17:57:38
@Maciej,看起来你是对的 - 我在这里滥用这个词。我会编辑以澄清这一点。 – 2010-07-08 18:02:13
当你做(1<<31)
,符号位的MSB被设置(变为1)。然后,当你做正确的转变时,它是符号扩展。因此,你得到-1。解决方案:(1UL < < 31)>> 31.
糟糕,Carl已经回答了。 – 341008 2010-07-08 17:55:54
位表示在对整数变量执行“such”左移时设置的符号。因此,结果。
- 1. 位移问题
- 2. 按钮文字移位问题
- 3. Perl移位问题
- 4. Javascript按位问题
- 5. 按位与,按位或问题,在Java
- 6. Windows 64位移植问题
- 7. Linux 64位移植问题
- 8. 移动定位问题
- 9. 移位div的问题
- 10. 凯撒移位问题
- 11. Jquery移动按钮问题
- 12. 按位运行问题
- 13. 按位移 -
- 14. C按位移
- 15. 使用移位除法的问题
- 16. 滚动位移过冲 - 数学问题
- 17. 64位可移植性问题
- 18. GLSL - 左,右移位操作问题
- 19. 移位时间计算问题
- 20. 位在C#中转移问题
- 21. 64位迁移问题:指针变化
- 22. 用javascript移动按钮的问题
- 23. jQuery移动按钮对齐问题
- 24. C#EF Linq的按位问题
- 25. HTML单位登录问题/按钮
- 26. fullpage.js问题定位导航按钮
- 27. vb.net - 十六进制,按位问题
- 28. 重新定位Flex按钮的问题
- 29. Facebook喜欢按钮位置问题
- 30. Android:按钮与RelativeLayout定位问题
特别要小心,有符号值的右移是编译器依赖的。所以在这里看到的输出只适用于特定平台,其他平台可能会给出其他结果。 – 2010-07-08 18:46:15
确实如此,但这并不会使使用无符号或更长变量的修复无效。我认为。 – 2010-07-08 19:09:55