gitee.com/quant1x/num@v0.3.2/type_float32.go (about) 1 package num 2 3 import ( 4 "fmt" 5 "gitee.com/quant1x/gox/exception" 6 "gitee.com/quant1x/gox/logger" 7 "gitee.com/quant1x/num/x32" 8 "math" 9 "reflect" 10 "strconv" 11 ) 12 13 const ( 14 errorFloat32Base = errorTypeBase + int(reflect.Float32)*100 15 ) 16 17 const ( 18 MaxFloat32 = float32(math.MaxFloat32) // float32最大值 19 MinFloat32 = float32(math.SmallestNonzeroFloat32) // float32最小值 20 StringTrue2Float32 float32 = float32(1) // 字符串true转float32 21 StringFalse2Float32 float32 = float32(0) // 字符串false转float32 22 ) 23 24 var ( 25 __nilToFloat32 = float32(math.NaN()) 26 ) 27 28 func Float32NaN() float32 { 29 return float32(NaN()) 30 } 31 32 // Float32IsNaN 判断float32是否NaN 33 func Float32IsNaN(f float32) bool { 34 return Float64IsNaN(float64(f)) 35 } 36 37 // 普通的处理方式, 将切片强制转换成float32 38 func sliceNumberToFloat32[T Number](s []T) []float32 { 39 count := len(s) 40 if count == 0 { 41 return []float32{} 42 } 43 d := make([]float32, count) 44 for idx, iv := range s { 45 // 强制转换 46 d[idx] = float32(iv) 47 } 48 return d 49 } 50 51 // SliceToFloat32 any输入只能是一维slice或者数组 52 func SliceToFloat32(v any) []float32 { 53 var vs []float32 54 switch values := v.(type) { 55 case []int8: 56 return sliceNumberToFloat32(values) 57 case []uint8: 58 return sliceNumberToFloat32(values) 59 case []int16: 60 return sliceNumberToFloat32(values) 61 case []uint16: 62 return sliceNumberToFloat32(values) 63 case []int32: // 加速 64 return x32.FromInt32(values) 65 case []uint32: 66 return sliceNumberToFloat32(values) 67 case []int64: // 加速 68 return x32.FromInt64(values) 69 case []uint64: 70 return sliceNumberToFloat32(values) 71 case []int: 72 return sliceNumberToFloat32(values) 73 case []uint: 74 return sliceNumberToFloat32(values) 75 case []float32: // 克隆 76 //return slices.Clone(values) 77 return values 78 case []float64: // 加速 79 return x32.FromFloat64(values) 80 case []bool: 81 count := len(values) 82 if count == 0 { 83 return []float32{} 84 } 85 // 加速 86 return x32.FromBool(values) 87 case []string: 88 count := len(values) 89 if count == 0 { 90 return []float32{} 91 } 92 vs = make([]float32, count) 93 for idx, iv := range values { 94 vs[idx] = float32(AnyToFloat64(iv)) 95 } 96 default: 97 vv := reflect.ValueOf(v) 98 vk := vv.Kind() 99 panic(exception.New(errorFloat32Base+0, fmt.Sprintf("Unsupported type: %s", vk.String()))) 100 } 101 return []float32{} 102 } 103 104 // ParseFloat32 字符串转float32 105 func ParseFloat32(s string, v any) float32 { 106 defer func() { 107 // 解析失败以后输出日志, 以备检查 108 if err := recover(); err != nil { 109 logger.Errorf("ParseFloat32 %+v, error=%+v\n", v, err) 110 } 111 }() 112 113 if IsEmpty(s) { 114 // TODO:NaN是针对64位, 这样直接转换应该有问题, 需要进一步确认 115 return __nilToFloat32 116 } 117 if StringIsTrue(s) { 118 return StringTrue2Float32 119 } else if StringIsFalse(s) { 120 return StringFalse2Float32 121 } 122 123 f, err := strconv.ParseFloat(s, 32) 124 if err == nil { 125 return float32(f) 126 } 127 if IgnoreParseExceptions { 128 return __nilToFloat32 129 } 130 _ = v.(float32) // Intentionally panic 131 return __nilToFloat32 132 } 133 134 func AnyToFloat32(v any) float32 { 135 if vv, ok := ExtractValueFromPointer(v); ok { 136 v = vv 137 } 138 139 f := valueToNumber(v, __nilToFloat32, BoolToFloat32, ParseFloat32) 140 return f 141 }