精華區beta C_and_CPP 關於我們 聯絡資訊
※ 引述《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
loveme00835:我記得是用"邏輯移位" & "算術移位" 來區分他們 12/07 20:43
LPH66:x86 的易記指令正是這樣分的... SAR 的 A 就是"算術" 12/07 20:49
loveme00835:蠻奇怪為啥不是 SLR XD 12/07 20:57
purpose:表示一個純粹shift所以用sh吧 12/07 21:01
wawi:同意一樓~ 12/07 21:30
scrush:感謝LPH66大的精闢講解,小弟我明白了,我也正在使用MCU中 12/07 22:31
scrush:遇到這裡有小小的疑惑.... 12/07 22:31