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) } }