diff --git a/to_int64.go b/to_int64.go index 51633a9..5825db8 100644 --- a/to_int64.go +++ b/to_int64.go @@ -2,7 +2,7 @@ package convx import ( "errors" - "strconv" + "math/big" ) // interface 转 int64 @@ -37,7 +37,15 @@ func ToInt64(val interface{}) (i int64, err error) { case float64: return int64(v), nil case string: - return strconv.ParseInt(v, 10, 64) + num := new(big.Float) + _, ok := num.SetString(v) + if !ok { + return 0, errors.New("convx.ToInt64: out of range") + } + + i, _ := num.Int64() + // fmt.Println(val, i, b) + return i, nil case bool: if v { return 1, nil @@ -47,4 +55,3 @@ func ToInt64(val interface{}) (i int64, err error) { } return 0, errors.New("convx.ToInt64: unknown type") } - diff --git a/to_int64_test.go b/to_int64_test.go index cfd2fd2..f4e841a 100644 --- a/to_int64_test.go +++ b/to_int64_test.go @@ -12,30 +12,34 @@ func TestToInt64(t *testing.T) { output int64 isError bool }{ - {"123", 123, false}, - {123.456, 123, false}, - {true, 1, false}, - {"abc", 0, true}, // - {nil, 0, true}, - {123, 123, false}, - {int32(123), 123, false}, - {uint64(123), 123, false}, - {int64(123), 123, false}, - {float32(123.456), 123, false}, - {float64(123.456), 123, false}, - {"-123", -123, false}, - {"123.456", 123, false}, // TODO: should be 123 + {"123", 123, false}, // string + {123.456, 123, false}, // float64 + {true, 1, false}, // bool + {"abc", 0, true}, // string + {nil, 0, true}, // nil + {123, 123, false}, // int + {int32(123), 123, false}, // int32 + {uint64(123), 123, false}, // uint64 + {int64(123), 123, false}, // int64 + {float32(123.456), 123, false}, // float32 + {float64(123.456), 123, false}, // float64 + {"-123", -123, false}, // string + {"123.456", 123, false}, // string {"170141183460469231731687303715884105727", 9223372036854775807, false}, // max int64 {"-170141183460469231731687303715884105728", -9223372036854775808, false}, // min int64 {"9223372036854775807", 9223372036854775807, false}, // max int64 {"-9223372036854775808", -9223372036854775808, false}, // min int64 - {"12345678901234567890", 0, false}, // too large + {"12345678901234567890", 9223372036854775807, false}, // too large } - for _, test := range tests { + for idx, test := range tests { output, err := convx.ToInt64(test.input) - if err != nil { - t.Error("ToInt64(", test.input, ") should not return error") + if test.isError && err == nil { + t.Error(idx, ": ToInt64(", test.input, ") should return error") + continue + } else if !test.isError && err != nil { + t.Error(idx, ": ToInt64(", test.input, ") should not return error", err.Error()) + continue } if output != test.output { t.Error("ToInt64(", test.input, ") should be", test.output, "but was", output)