如果我有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. Android位圖移位/移動問題
- 5. Javascript按位問題
- 6. 按位與,按位或問題,在Java
- 7. 移位div的問題
- 8. 凱撒移位問題
- 9. Linux 64位移植問題
- 10. 移動定位問題
- 11. Windows 64位移植問題
- 12. Jquery移動按鈕問題
- 13. PHP在32位左移位問題
- 14. 按鈕位置問題
- 15. 按位標誌問題
- 16. 按鈕定位的問題
- 17. 按位運行問題
- 18. C按位移
- 19. 按位移 -
- 20. 按位移位精度
- 21. Firefox自舉網格位移問題
- 22. 使用移位除法的問題
- 23. GLSL - 左,右移位操作問題
- 24. 在C++中循環移位的問題
- 25. Mecanim +帶位移問題的動畫
- 26. 64位可移植性問題
- 27. 移位時間計算問題
- 28. 64位遷移問題:指針變化
- 29. java按位左移
- 30. jQuery移動按鈕對齊問題
特別要小心,有符號值的右移是編譯器依賴的。所以在這裏看到的輸出只適用於特定平臺,其他平臺可能會給出其他結果。 – 2010-07-08 18:46:15
確實如此,但這並不會使使用無符號或更長變量的修復無效。我認爲。 – 2010-07-08 19:09:55