golang 計算機補碼、反碼、補碼、進位制相互轉換
阿新 • • 發佈:2020-12-21
對於整數,有四種表示方式: 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