Comparison of different types of Golang

Posted by BMorganVA on Wed, 31 Jul 2019 05:10:04 +0200

In the daily development process, we will inevitably encounter the comparison and operation of various types of variables. Here we have made some simple summaries, hoping to help students in the development.

Here we start with the last wave of relational operators==,!=,<,<=,> and>=.

float floating point comparison

Goang supports two kinds of floating-point float32 and float64. As we all know, when it comes to floating-point comparison or operation, it will encounter accuracy problems, which should be determined according to the implementation of IEEE 754 by Goang.

By default, float32 has a precision of 7 decimal places and float64 has a precision of 15 decimal places.

Example 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

Here we write a simple class of float comparisons based on accuracy, and pay attention to the maximum accuracy of 15 decimal points, beyond which accuracy will be lost.

Examples:

package main

import (
    "fmt"
    "math"
)

type Floater struct {
    Accuracy float64   //Accuracy, maximum 15 digits after decimal point
}
//Is it equal?
func (f Floater) IsEqual(a, b float64) bool {
    return math.Abs(a-b) < f.Accuracy
}
//0 equals 1, a is greater than b-1, a is less than 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
}

By the way, how to realize the retention of the last two decimal places?

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

Pointer type comparison

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

When the variables are the same or all nil, the pointer values are equal.

interface type comparison

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
}

Compare slice/struct/map

All three can be judged by reflection. 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

Topics: Go less