diff --git a/dataframe.go b/dataframe.go index 2f7d827969f31dabc40c61b138a22d0771e47972..218ddc667c6f1814d1fe7964bfbdcbf7814b7bb8 100644 --- a/dataframe.go +++ b/dataframe.go @@ -256,7 +256,7 @@ func checkColumnsDimensions(se ...Series) (nrows, ncols int, err error) { func (df DataFrame) Types() []string { coltypes := make([]string, df.ncols) for i, s := range df.columns { - coltypes[i] = s.Type() + coltypes[i] = s.Type().String() } return coltypes } @@ -487,5 +487,5 @@ func parseType(s string) (Type, error) { case "bool": return SERIES_TYPE_BOOL, nil } - return "", fmt.Errorf("type (%s) is not supported", s) + return SERIES_TYPE_INVAILD, fmt.Errorf("type (%s) is not supported", s) } diff --git a/dataframe_records.go b/dataframe_records.go index 798a8717682c3600407c4dff2035a56414c242fb..6c14403879b87bbcad672a8166771a45e661c2d3 100644 --- a/dataframe_records.go +++ b/dataframe_records.go @@ -2,7 +2,6 @@ package pandas import ( "fmt" - "strconv" ) // LoadRecords creates a new DataFrame based on the given records. @@ -12,7 +11,7 @@ func LoadRecords(records [][]string, options ...LoadOption) DataFrame { defaultType: SERIES_TYPE_STRING, detectTypes: true, hasHeader: true, - nanValues: []string{"NA", "NaN", ""}, + nanValues: PossibleNaOfString, } // Set any custom load options @@ -49,6 +48,7 @@ func LoadRecords(records [][]string, options ...LoadOption) DataFrame { rawcol := make([]string, len(records)) for j := 0; j < len(records); j++ { rawcol[j] = records[j][i] + // 收敛NaN的情况, 统一替换为NaN if findInStringSlice(rawcol[j], cfg.nanValues) != -1 { rawcol[j] = "NaN" } @@ -59,7 +59,7 @@ func LoadRecords(records [][]string, options ...LoadOption) DataFrame { if !ok { t = cfg.defaultType if cfg.detectTypes { - if l, err := findType(rawcol); err == nil { + if l, err := findTypeByString(rawcol); err == nil { t = l } } @@ -93,38 +93,3 @@ func LoadRecords(records [][]string, options ...LoadOption) DataFrame { } return df } - -func findType(arr []string) (Type, error) { - var hasFloats, hasInts, hasBools, hasStrings bool - for _, str := range arr { - if str == "" || str == "NaN" { - continue - } - if _, err := strconv.Atoi(str); err == nil { - hasInts = true - continue - } - if _, err := strconv.ParseFloat(str, 64); err == nil { - hasFloats = true - continue - } - if str == "true" || str == "false" { - hasBools = true - continue - } - hasStrings = true - } - - switch { - case hasStrings: - return SERIES_TYPE_STRING, nil - case hasBools: - return SERIES_TYPE_BOOL, nil - case hasFloats: - return SERIES_TYPE_FLOAT, nil - case hasInts: - return SERIES_TYPE_INT, nil - default: - return SERIES_TYPE_STRING, fmt.Errorf("couldn't detect type") - } -} diff --git a/dataframe_struct.go b/dataframe_struct.go index bb4d6238f14d5fc454db559d353a8bf1f0d9333b..cdd390f6defc11821287586760c94d104d92b9ab 100644 --- a/dataframe_struct.go +++ b/dataframe_struct.go @@ -48,7 +48,7 @@ func LoadStructs(i interface{}, options ...LoadOption) DataFrame { defaultType: SERIES_TYPE_STRING, detectTypes: true, hasHeader: true, - nanValues: []string{"NA", "NaN", "nan", ""}, + nanValues: PossibleNaOfString, } // Set any custom load options diff --git a/dataframe_type.go b/dataframe_type.go new file mode 100644 index 0000000000000000000000000000000000000000..bd874d5adafeab22bf220d68a5c487a1e8133ad5 --- /dev/null +++ b/dataframe_type.go @@ -0,0 +1,77 @@ +package pandas + +import ( + "fmt" + "strconv" +) + +func findTypeByString(arr []string) (Type, error) { + var hasFloats, hasInts, hasBools, hasStrings bool + for _, str := range arr { + if str == "" || str == "NaN" { + continue + } + if _, err := strconv.Atoi(str); err == nil { + hasInts = true + continue + } + if _, err := strconv.ParseFloat(str, 64); err == nil { + hasFloats = true + continue + } + if str == "true" || str == "false" { + hasBools = true + continue + } + hasStrings = true + } + + switch { + case hasStrings: + return SERIES_TYPE_STRING, nil + case hasBools: + return SERIES_TYPE_BOOL, nil + case hasFloats: + return SERIES_TYPE_FLOAT, nil + case hasInts: + return SERIES_TYPE_INT, nil + default: + return SERIES_TYPE_STRING, fmt.Errorf("couldn't detect type") + } +} + +// 检测类型 +func detectTypeBySlice(arr []any) (Type, error) { + var hasFloats, hasInts, hasBools, hasStrings bool + for _, v := range arr { + switch value := v.(type) { + case string: + hasStrings = true + continue + case float32, float64: + hasFloats = true + continue + case int, int32, int64: + hasInts = true + continue + case bool: + hasBools = true + continue + default: + _ = value + } + } + + switch { + case hasStrings: + return SERIES_TYPE_STRING, nil + case hasBools: + return SERIES_TYPE_BOOL, nil + case hasFloats: + return SERIES_TYPE_FLOAT, nil + case hasInts: + return SERIES_TYPE_INT, nil + default: + return SERIES_TYPE_STRING, fmt.Errorf("couldn't detect type") + } +} diff --git a/generic.go b/generic.go index 6224c91e4bd02f5cda7d50412f3e65459ff77e76..f7e732cb0bcede4e8035004ab42efdfe80a35da7 100644 --- a/generic.go +++ b/generic.go @@ -42,7 +42,7 @@ func NewNDFrame[E GenericType](name string, rows ...E) *NDFrame { type_: SERIES_TYPE_INVAILD, nilCount: 0, rows: 0, - //values: []E, + values: []E{}, } // TODO: 不知道rows是否存在全部为空的情况, 只能先创建一个空的slice frame.values = make([]E, 0) // Warning: filled with 0.0 (not NaN) @@ -67,7 +67,7 @@ func assign[T GenericType](frame *NDFrame, idx, size int, v T) { _vv := reflect.ValueOf(v) _vi := _vv.Interface() // float和string类型有可能是NaN, 对nil和NaN进行计数 - if frame.Type() == SERIES_TYPE_FLOAT && IsNaN(_vi.(float64)) { + if frame.Type() == SERIES_TYPE_FLOAT && Float64IsNaN(_vi.(float64)) { frame.nilCount++ } else if frame.Type() == SERIES_TYPE_STRING && StringIsNaN(_vi.(string)) { frame.nilCount++ @@ -366,13 +366,13 @@ func (self *NDFrame) FillNa(v any, inplace bool) { } case []int64: for idx, iv := range rows { - if IsNaN(float64(iv)) && inplace { + if Float64IsNaN(float64(iv)) && inplace { rows[idx] = AnyToInt64(v) } } case []float64: for idx, iv := range rows { - if IsNaN(iv) && inplace { + if Float64IsNaN(iv) && inplace { rows[idx] = AnyToFloat64(v) } } @@ -433,3 +433,67 @@ func (self *NDFrame) Max() any { } return Nil2Float64 } + +func (self *NDFrame) Min() any { + values := self.Values() + switch rows := values.(type) { + case []string: + min := "" + i := 0 + for idx, iv := range rows { + if StringIsNaN(iv) { + continue + } else if i < 1 { + min = iv + i += 1 + } + if iv < min { + min = iv + i += 1 + } + _ = idx + } + if i > 0 { + return min + } + return StringNaN + case []int64: + min := int64(0) + i := 0 + for idx, iv := range rows { + if Float64IsNaN(float64(iv)) { + continue + } else if i < 1 { + min = iv + i += 1 + } + if iv < min { + min = iv + i += 1 + } + _ = idx + } + return min + case []float64: + min := float64(0) + i := 0 + for idx, iv := range rows { + if Float64IsNaN(iv) { + continue + } else if i < 1 { + min = iv + i += 1 + } + if iv < min { + min = iv + i += 1 + } + _ = idx + } + if i > 0 { + return min + } + return Nil2Float64 + } + return Nil2Float64 +} diff --git a/generic_test.go b/generic_test.go index 9c702ac0ee5413871cc6d5bec887b510817cdafe..71fdbafb66a15650f38736a787d6425c5cc64cf5 100644 --- a/generic_test.go +++ b/generic_test.go @@ -2,36 +2,9 @@ package pandas import ( "fmt" - "reflect" "testing" ) -func TestNewSeriesFrame(t *testing.T) { - - //sf := NewSeries(SERIES_TYPE_STRING, "x", []string{"1", "2", "3"}) - //fmt.Println(sf) - - type args struct { - t string - name string - vals []interface{} - } - tests := []struct { - name string - args args - want *NDFrame - }{ - // TODO: Add test cases. - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := NewSeries(tt.args.t, tt.args.name, tt.args.vals...); !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewSeries() = %v, want %v", got, tt.want) - } - }) - } -} - func TestSeriesFrame(t *testing.T) { data := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} s1 := NewSeries(SERIES_TYPE_FLOAT, "x", data) @@ -63,6 +36,7 @@ func TestNDFrameNew(t *testing.T) { fmt.Println(nd11.Records()) fmt.Println(nd1.Max()) fmt.Println(nd1.Rolling(5).Max()) + fmt.Println(nd1.Rolling(5).Min()) nd12 := nd1.Rolling(5).Mean() d12 := nd12.Values() diff --git a/series.go b/series.go index bca22c3adcee4122698f493e4a873416c3b69fd8..010849296b3a05b9dc8d598e3763eecfaf84f5ef 100644 --- a/series.go +++ b/series.go @@ -9,15 +9,23 @@ import ( // Type is a convenience alias that can be used for a more type safe way of // reason and use Series types. -type Type = string +type Type = reflect.Kind // Supported Series Types +//const ( +// SERIES_TYPE_INVAILD = "unknown" // 未知类型 +// SERIES_TYPE_BOOL = "bool" // 布尔类型 +// SERIES_TYPE_INT = "int" // int64 +// SERIES_TYPE_FLOAT = "float" // float64 +// SERIES_TYPE_STRING = "string" // string +//) + const ( - SERIES_TYPE_INVAILD = "unknown" // 未知类型 - SERIES_TYPE_BOOL = "bool" // 布尔类型 - SERIES_TYPE_INT = "int" // int64 - SERIES_TYPE_FLOAT = "float" // float64 - SERIES_TYPE_STRING = "string" // string + SERIES_TYPE_INVAILD = reflect.Invalid // 无效类型 + SERIES_TYPE_BOOL = reflect.Bool // 布尔类型 + SERIES_TYPE_INT = reflect.Int64 // int64 + SERIES_TYPE_FLOAT = reflect.Float64 // float64 + SERIES_TYPE_STRING = reflect.String // string ) // StringFormatter is used to convert a value @@ -29,20 +37,20 @@ type Series interface { // Name 取得series名称 Name() string // Rename renames the series. - Rename(n string) + Rename(name string) // Type returns the type of data the series holds. - // 返回类型的字符串 + // 返回series的数据类型 Type() Type - // NRows 获得行数 + // Len 获得行数 Len() int // Values 获得全部数据集 Values() any // Empty returns an empty Series of the same type Empty() Series - // Records returns the elements of a Series as a []string - Records() []string // Copy 复制 Copy() Series + // Records returns the elements of a Series as a []string + Records() []string // Subset 获取子集 Subset(start, end int, opt ...any) Series // Repeat elements of an array. @@ -60,6 +68,8 @@ type Series interface { FillNa(v any, inplace bool) // Max 找出最大值 Max() any + // Min 找出最小值 + Min() any } // NewSeries 指定类型创建序列 @@ -212,7 +222,7 @@ func FillNa[T GenericType](s *NDFrame, v T, inplace bool) *NDFrame { } case []float64: for idx, iv := range rows { - if IsNaN(iv) && inplace { + if Float64IsNaN(iv) && inplace { rows[idx] = AnyToFloat64(v) } } diff --git a/series_ewm.go b/series_ewm.go index 0ece6285258e136f35c8a8316318961cc7cc571e..3fa50cf3081571f1161b827f28f77f48662f2593 100644 --- a/series_ewm.go +++ b/series_ewm.go @@ -124,7 +124,7 @@ func (ExponentialMovingWindow) adjustedMean(data Series, alpha DType, ignoreNA b w := alpha*weight + 1 x := values[t] - if IsNaN(x) { + if Float64IsNaN(x) { if ignoreNA { weight = w } @@ -145,14 +145,14 @@ func (ExponentialMovingWindow) notadjustedMean(data Series, alpha DType, ignoreN beta = 1 - alpha last = values[0] ) - if IsNaN(last) { + if Float64IsNaN(last) { last = 0 values[0] = last } for t := 1; t < len(values); t++ { x := values[t] - if IsNaN(x) { + if Float64IsNaN(x) { values[t] = last continue } diff --git a/series_float32.go b/series_float32.go new file mode 100644 index 0000000000000000000000000000000000000000..8457cce32387a317b4b7e211f7fdab26dd80558d --- /dev/null +++ b/series_float32.go @@ -0,0 +1,85 @@ +package pandas + +// TODO:留给于总的作业 +type SeriesFloat32 struct { + NDFrame +} + +func (self *SeriesFloat32) Name() string { + return self.name +} + +func (self *SeriesFloat32) Rename(n string) { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Type() Type { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Len() int { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Values() any { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Empty() Series { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Records() []string { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Copy() Series { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Subset(start, end int, opt ...any) Series { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Repeat(x any, repeats int) Series { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Shift(periods int) Series { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Rolling(window int) RollingWindow { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Mean() float64 { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) StdDev() float64 { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) FillNa(v any, inplace bool) { + //TODO implement me + panic("implement me") +} + +func (self *SeriesFloat32) Max() any { + //TODO implement me + panic("implement me") +} diff --git a/series_float64.go b/series_float64.go index 00c06a6c9c57a71240f369b245810e493363a338..63a2a13f5439a17dba405b4b055cd832a6250f26 100644 --- a/series_float64.go +++ b/series_float64.go @@ -77,7 +77,7 @@ func NewSeriesFloat64(name string, vals ...interface{}) *SeriesFloat64 { } func (self *SeriesFloat64) assign(idx, size int, f float64) { - if IsNaN(f) { + if Float64IsNaN(f) { self.nilCount++ } if idx < size { @@ -226,7 +226,7 @@ func (self *SeriesFloat64) FillNa(v any, inplace bool) { switch rows := values.(type) { case []float64: for idx, iv := range rows { - if IsNaN(iv) && inplace { + if Float64IsNaN(iv) && inplace { rows[idx] = AnyToFloat64(v) } } diff --git a/series_generic.go b/series_generic.go new file mode 100644 index 0000000000000000000000000000000000000000..4ff87418d4ca80bdc94ea00c22b85e35614259b2 --- /dev/null +++ b/series_generic.go @@ -0,0 +1,75 @@ +package pandas + +import ( + "reflect" +) + +var ( + typeBool = reflect.TypeOf([]bool{}) + typeInt64 = reflect.TypeOf([]int64{}) + typeFloat32 = reflect.TypeOf([]float32{}) + typeFloat64 = reflect.TypeOf([]float64{}) + typeString = reflect.TypeOf([]string{}) +) + +func CreateSeries(t Type, name string, v ...any) Series { + frame := NDFrame{ + formatter: DefaultFormatter, + name: name, + type_: SERIES_TYPE_INVAILD, + nilCount: 0, + rows: 0, + //values: []E{}, + } + return &frame +} + +func NewSeries2(name string, values ...interface{}) Series { + frame := NDFrame{ + formatter: DefaultFormatter, + name: name, + type_: SERIES_TYPE_INVAILD, + nilCount: 0, + rows: 0, + //values: []E{}, + } + _type, err := detectTypeBySlice(values) + //fmt.Println(_type, err) + if err != nil { + return nil + } + frame.type_ = _type + if frame.type_ == SERIES_TYPE_BOOL { + // bool + frame.values = reflect.MakeSlice(typeBool, 0, 0).Interface() + } else if frame.type_ == SERIES_TYPE_INT { + // int64 + frame.values = reflect.MakeSlice(typeInt64, 0, 0).Interface() + } else if frame.type_ == SERIES_TYPE_FLOAT { + // float64 + frame.values = reflect.MakeSlice(typeFloat64, 0, 0).Interface() + } else { + // string, 字符串最后容错使用 + frame.values = reflect.MakeSlice(typeString, 0, 0).Interface() + } + //series.Data = make([]float64, 0) // Warning: filled with 0.0 (not NaN) + //size := len(series.values) + size := 0 + for idx, v := range values { + if frame.type_ == SERIES_TYPE_BOOL { + val := AnyToBool(v) + assign[bool](&frame, idx, size, val) + } else if frame.type_ == SERIES_TYPE_INT { + val := AnyToInt64(v) + assign[int64](&frame, idx, size, val) + } else if frame.type_ == SERIES_TYPE_FLOAT { + val := AnyToFloat64(v) + assign[float64](&frame, idx, size, val) + } else { + val := AnyToString(v) + assign[string](&frame, idx, size, val) + } + } + + return &frame +} diff --git a/series_generic_test.go b/series_generic_test.go new file mode 100644 index 0000000000000000000000000000000000000000..82c1bf65a241569b9473994e390d1db8f343abe0 --- /dev/null +++ b/series_generic_test.go @@ -0,0 +1,32 @@ +package pandas + +import ( + "fmt" + "testing" +) + +func TestCreateSeries(t *testing.T) { + t0 := []any{1, true, "abc", 3.45, NaN()} + df0 := NewSeries2("x", t0...) + fmt.Printf("%+v\n", df0) + + s1 := NewSeries2("sales", nil, 50.3, 23.4, 56.2) + fmt.Println(s1) + + var values any + values = make([]float64, 0) + values = append(values.([]float64), 1) + fmt.Printf("%+v\n", values) + + //s1 := []string{"1", "2"} + //t1 := SERIES_TYPE_STRING + //if t1 == SERIES_TYPE_STRING { + // s2 := reflect.MakeSlice(typeString, 0, 0).Interface() + // //st1 := reflect.TypeOf(s1) + // //s2 := reflect.New(st1).Interface() + // s2 = append(s2.([]string), "1") + // fmt.Printf("%+v\n", s1) + // fmt.Printf("%+v\n", s2) + //} + +} diff --git a/series_int64.go b/series_int64.go index 4b2dbb3da7ccbd0e6e59e3f0fb6e878e4a0a2b9b..750f9d7719c2a18e3c60e3c8928b423f1e831bc4 100644 --- a/series_int64.go +++ b/series_int64.go @@ -185,7 +185,7 @@ func (self *SeriesInt64) FillNa(v any, inplace bool) { switch rows := values.(type) { case []int64: for idx, iv := range rows { - if IsNaN(float64(iv)) && inplace { + if Float64IsNaN(float64(iv)) && inplace { rows[idx] = AnyToInt64(v) } } diff --git a/series_number.go b/series_number.go index 7f247d97bfa565542d20bad322c3c8fea855875b..b87ef2d94a83a848cef5cb1178042c6aed2c1fb5 100644 --- a/series_number.go +++ b/series_number.go @@ -47,8 +47,10 @@ func Mean[T Number](x []T) float64 { } // any转number -func value_to_number[T Number](v any, bool2t func(b bool) T, string2t func(s string, v any) T) T { +func value_to_number[T Number](v any, nil2t T, bool2t func(b bool) T, string2t func(s string, v any) T) T { switch val := v.(type) { + case nil: // 这个地方判断nil值 + return nil2t case int8: return T(val) case uint8: diff --git a/series_rolling.go b/series_rolling.go index cad43ab342ca9126a1b91808a2440b128fda58d2..7ef31fb18fc7b6475a7a7808b1ef9f42614ebfba 100644 --- a/series_rolling.go +++ b/series_rolling.go @@ -66,3 +66,27 @@ func (r RollingWindow) Max() any { return fs } } + +func (r RollingWindow) Min() any { + var fs []float64 + var is []int64 + var ss []string + for _, block := range r.getBlocks() { + v := block.Min() + switch val := v.(type) { + case float64: + fs = append(fs, val) + case int64: + is = append(is, val) + case string: + ss = append(ss, val) + } + } + if len(ss) > 0 { + return ss + } else if len(is) > 0 { + return is + } else { + return fs + } +} diff --git a/type_bool.go b/type_bool.go index 3eee110bd8dad7d30e777fdbfe988ac222f4e2fc..d72241f5b84f72bf6967a7c143095ec4abe7058c 100644 --- a/type_bool.go +++ b/type_bool.go @@ -133,7 +133,7 @@ func int2Bool[T ~int | ~int32 | int64](n T) bool { } func float2Bool[T ~float32 | float64](f T) bool { - if IsNaN(float64(f)) || f == 0 { + if Float64IsNaN(float64(f)) || f == 0 { return false } return true diff --git a/type_float32.go b/type_float32.go index 7b7e774c2e6537437d1303e9624c3bd154d1bf2e..a8ac25c8c38b8ba9ae5d6561bae9d76c463110af 100644 --- a/type_float32.go +++ b/type_float32.go @@ -15,7 +15,7 @@ const ( // Float32IsNaN 判断float32是否NaN func Float32IsNaN(f float32) bool { - return IsNaN(float64(f)) + return Float64IsNaN(float64(f)) } // ParseFloat32 字符串转float32 @@ -60,6 +60,6 @@ func AnyToFloat32(v any) float32 { if isPoint(v) { return point_to_number[float32](v, Nil2Float32, boolToFloat32, ParseFloat32) } - f := value_to_number[float32](v, boolToFloat32, ParseFloat32) + f := value_to_number[float32](v, Nil2Float32, boolToFloat32, ParseFloat32) return f } diff --git a/type_float32_test.go b/type_float32_test.go index aef3611de7fd18c57e55e96b827158f39bfc5a34..ac804499c95db3a62d052bd12d4e95be41f84273 100644 --- a/type_float32_test.go +++ b/type_float32_test.go @@ -207,7 +207,7 @@ func Test_point_to_float32(t *testing.T) { // t.Errorf("point_to_float32() = %v, want %v", got, tt.want) // } //} - if got := AnyToFloat32(tt.args.v); got != tt.want && !(IsNaN(float64(tt.want)) && IsNaN(float64(got))) { + if got := AnyToFloat32(tt.args.v); got != tt.want && !(Float64IsNaN(float64(tt.want)) && Float64IsNaN(float64(got))) { t.Errorf("AnyToFloat32() = %v, want %v", got, tt.want) } }) @@ -373,7 +373,7 @@ func Test_value_to_float32(t *testing.T) { // t.Errorf("value_to_float32() = %v, want %v", got, tt.want) // } //} - if got := AnyToFloat32(tt.args.v); !(got == tt.want || (IsNaN(float64(tt.want)) && IsNaN(float64(got)))) { + if got := AnyToFloat32(tt.args.v); !(got == tt.want || (Float64IsNaN(float64(tt.want)) && Float64IsNaN(float64(got)))) { t.Errorf("AnyToFloat32() = %v, want %v", got, tt.want) } }) diff --git a/type_float64.go b/type_float64.go index bd101c8ccb2f004e61ca2b2c1dcf06cc4ea215b8..f02fe907a964bb0249d58fc0829f63034ebadc8d 100644 --- a/type_float64.go +++ b/type_float64.go @@ -19,7 +19,7 @@ const ( // Float64IsNaN 判断float64是否NaN func Float64IsNaN(f float64) bool { - return IsNaN(f) + return math.IsNaN(f) || math.IsInf(f, 0) } // ParseFloat64 字符串转float64 @@ -62,6 +62,6 @@ func AnyToFloat64(v any) float64 { if isPoint(v) { return point_to_number[float64](v, Nil2Float64, boolToFloat64, ParseFloat64) } - f := value_to_number[float64](v, boolToFloat64, ParseFloat64) + f := value_to_number[float64](v, Nil2Float64, boolToFloat64, ParseFloat64) return f } diff --git a/type_int64.go b/type_int64.go index 510fd8f5b6bae2d718bf232cc8c86e40861a4cc5..92ef0a11cf9e035d50e5a2763f8e7f80e3e0c5bd 100644 --- a/type_int64.go +++ b/type_int64.go @@ -62,6 +62,6 @@ func AnyToInt64(v any) int64 { if isPoint(v) { return point_to_number[int64](v, Nil2Int64, boolToInt64, ParseInt64) } - f := value_to_number[int64](v, boolToInt64, ParseInt64) + f := value_to_number[int64](v, Nil2Int64, boolToInt64, ParseInt64) return f } diff --git a/type_string.go b/type_string.go index 5309cb92fe1826943ab8b400e47da9e1e9ea0251..15441b9ad028ae47174189546e0fc57d6764350e 100644 --- a/type_string.go +++ b/type_string.go @@ -13,6 +13,11 @@ const ( False2String = "false" // false转string ) +var ( + // PossibleNaOfString 有可能出现的NaN字符串的全部选项 + PossibleNaOfString = []string{"NA", "NaN", "nan", ""} +) + // AnyToString any转string func AnyToString(v any) string { switch val := v.(type) {