1. 程式人生 > 實用技巧 >go中異或運算帶來的疑惑

go中異或運算帶來的疑惑

最近在看go,遇到一個問題:

一時沒看明白一元運算的異或運算是如何得到結果值的,程式碼如下:

var b uint8 = 15
var c int8 = 15

fmt.Printf(" b: %08b \n", b)
fmt.Printf("^b: %08b \n", ^b)
fmt.Printf(" c: %08b \n", c)
fmt.Printf("^c: %08b \n", ^c)

// 執行結果
 b: 00001111 
^b: 11110000 
 c: 00001111 
^c: -0010000 
按位補足 ^ : 該運算子與異或運算子一同使用,即 m^x,對於無符號x使用“全部位設定為1”,對於有符號x 時使用 m=-1 。

看上面的程式碼,和解釋,對於無符號數值的運算比較好理解:

^15

等價於1111 1111 ^ 0000 1111

結果: 1111 0000

但對於有符號數是如何計算出-0010000 的呢?先上計算過程

^15

等價於 -1^15

等價於1000 0001 ^0000 1111 (這裡是原碼)

等價於1111 1111 ^0000 1111 (這裡是補碼)

結果1111 0000(這裡是補碼)

結果轉為原碼 1000 1111 (補碼) +1 --> 1001 000 (原碼)

涉及的概念:

原碼、反碼、補碼,及轉換過程

真值:符號位+數字的絕對值 就是真值:例如:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

這裡還有一個概念:就是在系統中,數值使用補碼來表示(儲存)

原因:可以看這裡https://zhuanlan.zhihu.com/p/91967268

由補碼求原碼

  -如果補碼的符號位為“0”,表示為正數,所以補碼就是該數的原碼。

  - 如果補碼的符號位為“1”,表示為負數,求原碼的操作是:符號位不變,即為1,其餘各位取反,然後再整個數加1

  示例

  1111 0000 -> 1000 1111->1000 1111 + 1-> 1001 0000

 

反碼通常是用來做 原碼和補碼轉碼的過渡。

其實是很基礎的知識,但是多年沒接觸過,導致忘光了

如果想複習的話,可以看一下這裡

原碼、反碼、補碼 詳解!不懂的請看過來!

https://www.cnblogs.com/resn/p/13396630.html