Re: [問題] 位移運算子的疑問
※ 引述《scrush (阿慶)》之銘言:
: 遇到的問題(Question):比如說一般的unsigned 所定義的變數是可以隨便用>>,<<
: 來做除或乘的動作,但變成signed定義時,是不是就不能這樣做了?是會因此改變sign bit
: 的關係?假如程式是這樣寫:
: signed long temp = 0x80000000;
: signed long Out;
: Out = (temp >> 16); <--A
: Out = (temp/65536); <--B
: 請問一下,是B對還是A對?如果B才是正確的,是否有其他方法可以在負數的情況下,使用
: 謝謝!
在 low level 的機器語言裡
右移有兩種 signed shift right 和 unsigned shift right
(x86 的易記指令分別叫做 SAR 和 SHR, shift arithmetic right 和 shift right)
差別在於右移時最高位會不會留著原來的 sign bit
signed shift right (即 x86 的 SAR) 會留著
unsigned shift right (即 x86 的 SHR) 會補 0
也就是 signed shift right 會讓負值依然變成負值
以 0x80000000 >> 1 來說就是這樣:
signed shift
┌┐
│↓
└1→0→0→0→………0→0→0→0
_||_
\/
1 1 0 0 ………0 0 0 0 (0xC0000000)
unsigned shift
0
↓
1→0→0→0→………0→0→0→0
_||_
\/
0 1 0 0 ………0 0 0 0 (0x40000000)
(相對的 左移只有一種 右邊一律補0
雖然 x86 的易記指令也有 SHL 和 SAL 兩個 但做的事完全一樣)
在 C 語言裡 兩個都是 >> 表示 實際上是哪一種則是看左邊是不是 unsigned
左邊是 unsigned 則用 unsigned shift right
左邊是 signed 則用 signed shift right
所以在你的例子裡 A 和 B 是一樣的結果 (都會變成 0xFFFF8000, -32768)
如果想要變成 0x00008000 的話則用 ((unsigned long)temp) >> 16 即可
這也就是為什麼用作 bit-field 的變數/常數通常會宣告成 unsigned 的原因
--
◢ ˊ_▂▃▄▂_ˋ. ◣ ▅▅ ▅▅ ι●╮ █▄▄▄▄▄
▍./◤_▂▃▄▂_◥ \'▊ HARUHI █████ <■┘ ▄▄▄▄▄▄▄
▎⊿ ◤◤◥█◥◥█Δ ISM By-gamejye ¢|\ ▌▌▌▌▌▄▌▌
▏ζ(▏●‵◥′●▊)Ψ ▏ █ ⊿Δ ▄▄▄ ▄▄▄▄
█/|▊ 〃 、 〃▋ |\ ▎ ハルヒ主義 █▄▄▄█▄▄
◥◥|◣ ‵′ ◢/'◢◢S.O.S 世界を大いに盛り上げるための涼宮ハルヒの団
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.30.81
推
12/07 20:43, , 1F
12/07 20:43, 1F
→
12/07 20:49, , 2F
12/07 20:49, 2F
→
12/07 20:57, , 3F
12/07 20:57, 3F
推
12/07 21:01, , 4F
12/07 21:01, 4F
→
12/07 21:30, , 5F
12/07 21:30, 5F
推
12/07 22:31, , 6F
12/07 22:31, 6F
→
12/07 22:31, , 7F
12/07 22:31, 7F
討論串 (同標題文章)