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  }