go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/convert.go (about) 1 package fu 2 3 import ( 4 "fmt" 5 "math" 6 "reflect" 7 "strconv" 8 ) 9 10 func Isna(v reflect.Value) bool { 11 if !v.IsValid() { 12 return true 13 } 14 switch v.Kind() { 15 case reflect.Float32, reflect.Float64: 16 return math.IsNaN(v.Float()) 17 } 18 return false 19 } 20 21 func Nan(tp reflect.Type) reflect.Value { 22 switch tp.Kind() { 23 case reflect.Float32: 24 return reflect.ValueOf(float32(math.NaN())) 25 case reflect.Float64: 26 return reflect.ValueOf(math.NaN()) 27 } 28 return reflect.Zero(tp) 29 } 30 31 func ConvertSlice(v reflect.Value, na Bits, tp reflect.Type, nocopy ...bool) reflect.Value { 32 L := v.Len() 33 vt := v.Type().Elem() 34 if vt == tp && Fnzb(nocopy...) { 35 return v.Slice(0, L) 36 } 37 r := reflect.MakeSlice(reflect.SliceOf(tp), L, L) 38 if vt == tp { 39 reflect.Copy(r, v) 40 } else { 41 for i := 0; i < L; i++ { 42 r.Index(i).Set(Convert(v.Index(i), na.Bit(i), tp)) 43 } 44 } 45 return r 46 } 47 48 func Convert(v reflect.Value, na bool, tp reflect.Type) reflect.Value { 49 if na { 50 return Nan(tp) 51 } 52 if v.Type() == tp { 53 return v 54 } else if tp.Kind() == reflect.String { 55 return reflect.ValueOf(fmt.Sprint(v.Interface())) 56 } else if v.Kind() == reflect.String { 57 switch tp.Kind() { 58 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 59 x, err := strconv.ParseInt(v.String(), 10, 64) 60 if err != nil { 61 panic(err) 62 } 63 return reflect.ValueOf(x).Convert(tp) 64 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 65 x, err := strconv.ParseUint(v.String(), 10, 64) 66 if err != nil { 67 panic(err) 68 } 69 return reflect.ValueOf(x).Convert(tp) 70 case reflect.Float32, reflect.Float64: 71 x, err := strconv.ParseFloat(v.String(), 64) 72 if err != nil { 73 panic(err) 74 } 75 return reflect.ValueOf(x).Convert(tp) 76 } 77 } else if tp.Kind() == reflect.Float32 { 78 switch v.Kind() { 79 case reflect.Float32: 80 return v 81 case reflect.Struct: 82 if q, ok := v.Interface().(Fixed8); ok { 83 return reflect.ValueOf(q.Float32()) 84 } 85 case reflect.Float64: 86 return reflect.ValueOf(float32(v.Float())) 87 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 88 return reflect.ValueOf(float32(v.Uint())) 89 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 90 return reflect.ValueOf(float32(v.Int())) 91 } 92 } else if tp.Kind() == reflect.Float64 { 93 switch v.Kind() { 94 case reflect.Float64: 95 return v 96 case reflect.Struct: 97 if q, ok := v.Interface().(Fixed8); ok { 98 return reflect.ValueOf(float64(q.Float32())) 99 } 100 case reflect.Float32: 101 return reflect.ValueOf(v.Float()) 102 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 103 return reflect.ValueOf(float64(v.Uint())) 104 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 105 return reflect.ValueOf(float64(v.Int())) 106 } 107 } 108 return v.Convert(tp) 109 }