C语言符号位补码要变吗,补码与符号位取反
補碼與符號位取反
先來一個 C 語言的小例子:
#include #include int main(void)
{
int16_t n = -1;
n &= 0x7FFF; // 按位與
printf("%d", n); // 這里輸出什么?
return 0;
}
對于16位的整數 n ,按位與運行將最高位設置為0(符號位),得到的結果卻不是 1 ,結果是 32767 。
原因在于有符號整數的實現方式。
有符號整數,最容易想到的方式是在最高位加一個符號位,0表示整數,1表示負數,其它位不變(保留原始值),也即是原碼方式。但這個方式有一個問題,存在兩個0,正0和負0,在計算時需要先判斷符號位,然后才能決定用加法還是減法,機器計算不便。
另外一個方法是負數全部按位取反,也就是反碼方式。這個運算就相對簡單了,進行加法時,按位計算,0和0為0,0為1為1,1和1為0并產生進位,最高位有進位時,結果要加1,減法可處理為其負數的加法。但還是有點問題,還存在兩個0,正0和負0。
問題是出現負數上,那么把負數的反碼 + 1 ,不就把負0去掉了嗎?還真的是這樣,而同時負數比整數能多表示一個數(這是基于同余的)。
嚴格的表達為:
對于位數為 n 的整數,其補碼 [x]補 為:(2^n + x) mod 2^n ,
表示的范圍為 -2^(n-1) <= n < 2^(n-1) ,注意正數最大為 2^(n-1)-1
即:
當 0 <= x < 2^(n-1) 時,
[x]補 = x 的原碼
當 -2^(n-1) <= x < 0 時,
[x]補 = 2^n + x 的原碼。
而經驗上,可看作負數的補碼為其反碼加1(特殊數 -2^(n-1) ) 的反碼 :
x < 0 時:
[x]補 = [x]反 + 1
特殊數 [ -2^(n-1) ] = 100...0
它的加法處理非常簡單,符號位也可以運行,
[x+y]補 = (2^n + x + y) mod 2^n = ((2^n + x) + (2^n + y)) mod 2^n = [x]補 + [y]補
[x-y]補 = (2^n + x - y) mod 2^n = ... = [x]補 + [-y]補
現在回到原來的問題,對于16位 -1 ,其補碼為:
[-1]補 = [-1]反 + 1 = 0xFFFFF
按位與去掉符號位,得到的是 0x7FFF 也就是16位整數最大的正數( 2^15 - 1) 32767。
總結
以上是生活随笔為你收集整理的C语言符号位补码要变吗,补码与符号位取反的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项目的数据存储c语言,C语言项目实战项目
- 下一篇: arm clz指令c语言,协处理器及其他