gitee.com/quant1x/num@v0.3.2/labs/testify.go (about) 1 package labs 2 3 import ( 4 "math" 5 "reflect" 6 ) 7 8 // 判断float是否NaN 9 func floatIsNaN[T ~float32 | ~float64](f T) bool { 10 return math.IsNaN(float64(f)) || math.IsInf(float64(f), 0) 11 } 12 13 // FloatEqual 浮点值相等或者均为NaN 14 func FloatEqual[T ~float32 | ~float64](got, want T) bool { 15 if got == want { 16 return true 17 } 18 gotIsNaN := floatIsNaN(got) 19 wantIsNaN := floatIsNaN(want) 20 return gotIsNaN && wantIsNaN 21 } 22 23 // SliceWantFloat 比较两个浮点切片 24 func SliceWantFloat[T ~float32 | ~float64](got, want []T) bool { 25 if len(got) != len(want) { 26 panic("slices must be of equal length") 27 } 28 b := 0 29 for i := 0; i < len(got); i++ { 30 //b1 := got[i] == want[i] || (math.IsNaN(want[i]) && math.IsNaN(got[i])) 31 if FloatEqual(float64(got[i]), float64(want[i])) { 32 b += 1 33 } 34 } 35 return b == len(got) 36 } 37 38 // DeepEqual 深度比较是否相等 39 // 40 // 这里重构的目的是float类型中NaN和Inf的处理, 从数据的逻辑层面上应该记作相等 41 func DeepEqual(x, y any) bool { 42 if x == nil || y == nil { 43 return x == y 44 } 45 v1 := reflect.ValueOf(x) 46 v2 := reflect.ValueOf(y) 47 if v1.Type() != v2.Type() { 48 return false 49 } 50 switch x.(type) { 51 case float32, float64: 52 f1 := v1.Float() 53 f2 := v2.Float() 54 return FloatEqual(f1, f2) 55 case []float32: 56 f1 := x.([]float32) 57 f2 := y.([]float32) 58 return SliceWantFloat(f1, f2) 59 case []float64: 60 f1 := x.([]float64) 61 f2 := y.([]float64) 62 return SliceWantFloat(f1, f2) 63 } 64 65 return reflect.DeepEqual(x, y) 66 }