1. 程式人生 > 實用技巧 >golang 計算機補碼、反碼、補碼、進位制相互轉換

golang 計算機補碼、反碼、補碼、進位制相互轉換

對於整數,有四種表示方式:
1)、二進位制:0,1 ,滿 2 進 1。在 golang 中,不能直接使用二進位制來表示一個整數,它沿用了 c 的特點。
2)、十進位制:0-9 ,滿 10 進 1。
3)、八進位制:0-7 ,滿 8 進 1. 以數字 0 開頭表示。
4)、十六進位制:0-9 及 A-F,滿 16 進 1. 以 0x 或 0X 開頭表示。此處的 A-F 不區分大小寫


簡單的格式化進位制輸出的示例
package main

import "fmt"

func main() {

	// 十進位制格式化為二進位制
	var i int = 5
	fmt.Printf("%b\n", i)
    
    // 八進位制格式化為十進位制
	var j int = 011
	fmt.Println("j=", j)

    // 十六進位制格式化為十進位制
	var k int = 0x11
	fmt.Println("k=", k)
}

1、二進位制、八進位制、十六進位制轉為十進位制

1.1、二進位制轉為十進位制
例如:1011
手動換算:1 * 2^(4-1) + 0 * 2^(3-1) + 1 * 2^(2-1) + 1 * 2^(1-1)
              8     +      0      +      2      +   1    =   11
              
程式碼運算:
	ret, _ := strconv.ParseInt("1011", 2, 64) // 11
1.2、八進位制轉為十進位制
例如:23
手動換算:2 * 8^(2-1) + 3 * 8^(1-1)
              16     +      3     =     19    
              
程式碼運算:
	ret, _ := strconv.ParseInt("23", 8, 64) // 19
1.3、十六進位制轉為十進位制
例如:23
手動換算:2 * 16^(2-1) + 3 * 16^(1-1)
              32     +      3     =     35  
              
程式碼運算:
	ret, _ := strconv.ParseInt("23", 16, 64) // 35

2、十進位制轉為二進位制、八進位制、十六進位制

2.1、十進位制轉為二進位制
例如:56
手動換算:         餘數,從下往上取值
	2 | 56   ...   0
	2 | 28   ...   0
	2 | 14   ...   0
	2 | 7    ...   1
	2 | 3    ...   1
	  1      ...   1
    111000
    
程式碼運算:
	ret := strconv.FormatInt(56, 2) // 111000
2.2、十進位制轉為八進位制
例如:56
手動換算:         餘數,從下往上取值
	8 | 56  ...  0
	  7     ...  7  //小於8,從下往上取值
    70
    
程式碼運算:
	ret := strconv.FormatInt(56, 8) // 70
2.3、十進位制轉為十六進位制
例如:56
手動換算:         餘數,從下往上取值
	16 | 56  ...   8
	   3     ...   3  //小於16,從下往上取值
    38
程式碼運算:
	ret := strconv.FormatInt(56, 16) // 38

3、二進位制轉為八進位制、十進位制、十六進位制

3.1、二進位制轉為八進位制
例如: 11010101
手動換算:每取3位,進行 4 2 1 按位的運算
    421=3  421=2   421=5
	011    010     101
	結果:0325

程式碼運算:
	// 2進位制轉為10進位制
	base_10, _ := strconv.ParseInt("11010101", 2, 64) //213

	// 10進位制轉為8進位制
	ret := fmt.Sprintf("%o", base_10) //325
	fmt.Println(ret)
3.2、二進位制轉為十六進位制
例如: 11010101
手動換算:每取4位,進行 8 4 2 1 按位的運算
        8421=13   8421=5
		1101      0101
		D5
程式碼運算:
	// 2進位制轉為10進位制
	base_10, _ := strconv.ParseInt("11010101", 2, 64) //213

	// 10進位制轉為16進位制
	ret := fmt.Sprintf("%X", base_10) //D5
	fmt.Println(ret)
3.3、二進位制轉為十進位制
例如: 11010101
手動換算:
		// 先轉為16進位制
		每取4位,進行 8 4 2 1 按位的運算
        8421=13   8421=5
		1101      0101
		D5
		// 然後再由十六進位制轉為10進位制
		D * (16^2-1) + 5 * (16^1-1) 
        13*16        + 5    =   213
程式碼運算:
	// 2進位制轉為10進位制
	base_10, _ := strconv.ParseInt("11010101", 2, 64) //213

4、八進位制、十進位制、十六進位制轉為二進位制

4.1、八進位制為二進位制
例如: 123
手動換算:採用:421,按位換算
	421    421   421 
	001    010   011
	  1     2      3
-----------------------
	123 ==> 001010011
程式碼運算:
	// 8進位制轉為2進位制
	ret := fmt.Sprintf("%b", 0123)
	fmt.Println(ret) //1010011
4.2、十進位制為二進位制
例如: 123
手動換算:取2,取餘數,從下往上取值
	2 | 123 ... 1
    2 |  61 ... 1
    2 |  30 ... 0
    2 |  15 ... 1
    2 |   7 ... 1
    2 |   3 ... 1
	2 |   1 ... 1
---------------------
    1111011
程式碼運算:
	// 10進位制轉為2進位制
	ret := fmt.Sprintf("%b", 123) // 1111011
	fmt.Println(ret) 
4.3、十六進位制為二進位制
例如: 123
手動換算:取4位,採用:8421,按位換算
	8421    8421   8421 
	0001    0010   0011
	1       2      3
-----------------------
	123 ==> 000100100011
程式碼運算:
	// 16進位制轉為2進位制
	ret := fmt.Sprintf("%b", 0x123)
	fmt.Println(ret) //100100011

5、原碼、反碼、補碼

1、二進位制最高位是符號位:0表示正數,1表示負數
2、正數的原碼、反碼、補碼都是一樣
3、負數的反碼=原碼符號位不變,其它位取反(0->1,1->0)
4、負數的補碼=反碼+1
5、0的反碼、補碼都是0
6、在計算機運算的時候都是以補碼的方式來運算
5.1、負數的&或|或^的運算示例
2 & -3
        原碼            反碼        補碼
2   =>  0000 0010   0000 0010   0000 0010
-3  =>  1000 0011   1111 1100   1111 1101
------------------------------------------------
                                0000 0000

2 | -3
        原碼            反碼        補碼
2   =>  0000 0010   0000 0010   0000 0010
-3  =>  1000 0011   1111 1100   1111 1101
------------------------------------------------
                                1111 1111
                                
                                反推為原碼:
         原碼       補碼         運算結果
         1000 0001  1111 1110   1111 1111
         結果為: -1

2 ^ -2
        原碼            反碼        補碼
2   =>  0000 0010   0000 0010   0000 0010
-2  =>  1000 0010   1111 1101   1111 1110
------------------------------------------------
                                1111 1100
                        
                                反推為原碼:
        反碼         補碼        運算結果
        1000 0100   1111 1011   1111 1100
        結果為: -4