Go 語言具有嚴格的靜態(tài)類型限制,運算符操作的數(shù)字類型必須是相同類型數(shù)據(jù)。且數(shù)字操作不能超出該類型的取值范圍,不然計算溢出得到的結(jié)果就是錯的。
一、加減乘除、取模
package main
import "fmt"
func main() {
// 加 +
var ui1, ui2 uint8
ui1 = 1
ui2 = 2
ui := ui1 + ui2
fmt.Println(ui) // 輸出:3
ui += 255
fmt.Println(ui) // 溢出后計算的值就是錯的,輸出:2
// 減 -
var i, j int32
i = 10
j = 5
fmt.Println(i - j) // 輸出:5
// 乘 *
var f1, f2 float32
f1 = 1.2
f2 = 0.2
// 浮點型的數(shù)字計算有精度問題,float32 精度6位小數(shù),float64 精度15位小數(shù),
fmt.Println(f1 * f2) // 輸出:0.24000001
// 除 /
n1 := 10
n2 := 3
fmt.Println(n1 / n2) // 輸出:3,小數(shù)被丟棄
// 求模、取余 %
fmt.Println(n1 % n2) // 輸出余數(shù):1
}
二、位運算
位運算是直接對數(shù)字在內(nèi)存中存儲的二進制數(shù)進行操作,所以性能上來講是最快的運算方式。位運算一般常見于需要性能優(yōu)化或復(fù)雜的算法中。位運算只作用于整數(shù)類型上。
Go 語言中的位運算符:
| 運算符 | 釋義 | 運算規(guī)則 |
|---|---|---|
| & | 按位與,兩個數(shù)對應(yīng)的二進制位相與 | 同時為1,則為1,否則為0 |
| | | 按位或,兩個數(shù)對應(yīng)的二進制位相或 | 有一個為1,則為1,否則為0 |
| ^ | 按位異或,兩個數(shù)對應(yīng)的二進制位相異或 | 二進制位不同,則為1,否則為0 |
| &^ | 按位清空 | x&^y 如果ybit位上的數(shù)是0則取x上對應(yīng)位置的值,如果ybit位上為1則結(jié)果位上取0 |
| << | 左移 | 所有二進制位左移運算符右邊指定的位數(shù),高位丟棄,低位補0。左移n位就是乘以2的n次方 |
| >> | 右移 | 所有二進制位右移運算符右邊指定的位數(shù),高位補0,低位丟棄。右移n位就是除以2的n次方 |
package main
import "fmt"
func main() {
var i1, i2, n uint8 // 1個字節(jié)
// 按位與 &
i1 = 2 // 二進制:0000 0010
i2 = 3 // 二進制:0000 0011
n = i1 & i2 // 按位與:0000 0010
fmt.Println(n) // 輸出:2
// 按位或 |
i1 = 10 // 二進制:0000 1010
i2 = 20 // 二進制:0001 0100
n = i1 | i2 // 按位或:0001 1110
fmt.Println(n) // 輸出:30
// 按位異或 ^
i1 = 3 // 二進制:0000 0011
i2 = 4 // 二進制:0000 0100
n = i1 ^ i2 // 按位異或:0000 0111
fmt.Println(n) // 輸出:7
// 按位清空 &^
i1 = 10 // 二進制:0000 1010
i2 = 20 // 二進制:0001 0100
n = i1 &^ i2 // 按位清空:0000 1010
fmt.Println(n) // 輸出:10
// 左移 <<
i1 = 5 // 二進制 0000 0101
n = i1 << 2 // 左移2位:0001 0100
fmt.Println(n) // 輸出:20
// 右移 >>
i2 = 15 // 二進制:0000 1111
n = i2 >> 2 // 右移2位:0000 0011
fmt.Println(n) // 輸出:3
}
三、比較大小
大小比較得到的類型時布爾型。運算符:>大于、>=大于等于、<小于、<=小于等于、==等于。
package main
import "fmt"
func main() {
fmt.Println(2 > 1) // 輸出:true
fmt.Println(1 == 2) // 輸出:false
}
四、數(shù)字類型轉(zhuǎn)換
整型從高位類型轉(zhuǎn)低位類型會有精度丟失,浮點型轉(zhuǎn)整型會丟失小數(shù)點后的值,復(fù)數(shù)型轉(zhuǎn)非復(fù)數(shù)整型時符號丟失。數(shù)據(jù)類型轉(zhuǎn)換格式:目標類型(轉(zhuǎn)換類型)
package main
import "fmt"
func main() {
// 整型轉(zhuǎn)浮點型
var i int = 1
fmt.Printf("%f\n", float32(i)) // 輸出:1.000000
// 浮點型轉(zhuǎn)整型
var f float32 = 3.1415926
fmt.Printf("%d\n", int(f)) // 輸出:3,小數(shù)后丟失
// float32 轉(zhuǎn) float64
fmt.Printf("%v\n", float64(f)) // 輸出:3.141592502593994,6位后的小數(shù)精度是錯誤的
// float64 轉(zhuǎn) float32
var f2 float64 = 3.141592653589793
fmt.Println("%v\n", float32(f2)) // 輸出:3.1415927,6位后的小數(shù)精度是錯誤的
}
五、數(shù)字轉(zhuǎn)字符串
使用 strconv 包中定義的函數(shù)做數(shù)字和字符串轉(zhuǎn)換。
package main
import (
"fmt"
"strconv"
)
func main() {
// int 轉(zhuǎn) string
var i int = 111
var s string
s = strconv.Itoa(i) // 數(shù)字轉(zhuǎn)字符串
fmt.Println(s)
// string 轉(zhuǎn) int
i2, err := strconv.ParseInt(s, 10, 64) // 把 s 轉(zhuǎn)為10進制64位數(shù)
if err == nil {
fmt.Println(i2) // 輸出:111
}
// float 轉(zhuǎn) string
var f float64 = 3.1415926535
s1 := strconv.FormatFloat(f, 'f', -1, 64)
fmt.Println(s1) // 輸出:3.1415926535
// 第二個參數(shù)選項,含義如下:
// 'b' (-ddddp±ddd,二進制指數(shù))
// 'e' (-d.dddde±dd,十進制指數(shù))
// 'E' (-d.ddddE±dd,十進制指數(shù))
// 'f' (-ddd.dddd,沒有指數(shù))
// 'g' ('e':大指數(shù),'f':其它情況)
// 'G' ('E':大指數(shù),'f':其它情況)
// string 轉(zhuǎn) float
str := `3.1415926535`
v1, err := strconv.ParseFloat(str, 32) // ParseFloat 函數(shù)默認返回float64類型數(shù)據(jù),轉(zhuǎn)成folat32可能會有精度丟失
if err == nil {
fmt.Printf("%v\n", v1) // 輸出:3.1415927410125732
}
v2, err := strconv.ParseFloat(str, 64)
if err == nil {
fmt.Printf("%v\n", v2) // 輸出:3.1415926535
}
}