Golang不同類型比較

在日常開發過程中難免會遇到各個類型的變量的比較以及運算操作,這裏我們做了一些簡單的彙總,希望能給各位同學在開發中帶來幫助。

這裏先上一波關係運算符==,!=,<,<=,> 和 >=。

float浮點數比較

golang 支持兩種浮點float32和float64,衆所衆知,涉及浮點數比較或運算是會遇到精度問題,具體要根據golang實現IEEE 754的情況定。

默認情況下,float32精度是小數後7位,float64精度是小數點後15位。

如例1:

    var a float32 = 1.00000001
    var b float32 = 1.000000000001
    var c float32 = 1.0000001
    var d float32 = 1.000000000001

    fmt.Println(a == b) //true
    fmt.Println(a > b)  //false
    fmt.Println(c == d) //false
    fmt.Println(c > d)  //true

float64

    var a float64 = 1.0000000000000001
    var b float64 = 1.000000000000000001
    var c float64 = 1.000000000000001
    var d float64 = 1.0000000000000000001

    fmt.Println(a == b) //true
    fmt.Println(a > b)  //false
    fmt.Println(c == d) //false
    fmt.Println(c > d)  //true

這裏寫了一個根據精度進行float比較的簡單的類,注意最大精度爲小數點後15位,超出會丟失精度。

示例:

package main

import (
    "fmt"
    "math"
)

type Floater struct {
    Accuracy float64   //精度,最大爲小數點後15位
}
//是否相等
func (f Floater) IsEqual(a, b float64) bool {
    return math.Abs(a-b) < f.Accuracy
}
//0爲相等 1爲a大於b -1爲a小於b
func (f Floater) Bccomp(a, b float64) int8 {
    if math.Abs(a-b) < f.Accuracy {
        return 0
    }
    if math.Max(a, b) == a {
        return 1
    } else {
        return -1
    }
}

func main() {

    f := Floater{Accuracy: 0.000000000001}
    var a float64 = 1.0000000002
    var b float64 = 1.0000000001

    fmt.Println(f.Bccomp(a, b)) //1
    fmt.Println(f.Bccomp(b, a)) //-1
    fmt.Println(f.Bccomp(a, a)) //0
}

順便講一下如何實現保留小數點後2位如何實現

    //方法1
    a := 2.556
    v, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", a), 64)
    fmt.Println(v)   //2.56
    //方法2   
    v = math.Trunc(a*1e2+0.5) * 1e-2
    fmt.Println(v)   //2.56
    
    //方法3
    n10 := math.Pow10(2)
    v = math.Trunc((a+0.5/n10)*n10) / n10
    fmt.Println(v)

指針類型比較

    a := "hello"
    b := &a
    c := &a
    fmt.Println(b == c)

當變量是相同或者都爲nil時,指針值相等。

interface類型比較

type I1 interface {
    f()
}
type I2 interface {
    f()
}

type S1 struct {
    name string
}

func (s S1) f() {
}

type S2 struct {
    name string
}

func (s S2) f() {   
}

func main() {
    var a, b, c, d I1
    var e I2
    a = S1{"hello"}
    b = S1{"hello"}
    c = S1{"world"}
    d = S2{"hello"}
    fmt.Println(a == b) //true
    fmt.Println(a == c) //false
    fmt.Println(a == d) //false
    fmt.Println(a == e) //false
}

比較 slice/struct/map

這三個都可以用reflect.DeepEqual來判斷是否相等

package main

import (
    "fmt"
    "reflect"
)

type S struct {
    s string
}

func main() {
    s1 := S{s: "hello"}
    s2 := S{s: "hello"}
    if reflect.DeepEqual(s1, s2) {
        fmt.Println(s1, "==", s2)
    }

    a1 := []int{1, 2}
    a2 := []int{1, 2}
    if reflect.DeepEqual(a1, a2) {
        fmt.Println(a1, "==", a2)
    }

    m1 := map[int]string{1: "a", 2: "b"}
    m2 := map[int]string{1: "a", 2: "b"}
    if reflect.DeepEqual(m1, m2) {
        fmt.Println(m1, "==", m2)
    }
}

links

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章