Merge pull request #306 from pingcap/siddontang/decimal-scientific-notation

mysqldef: support parsing scientific notation
This commit is contained in:
siddontang
2015-10-07 09:56:44 +08:00
2 changed files with 54 additions and 3 deletions

View File

@ -199,17 +199,28 @@ func NewDecimalFromUint(value uint64, exp int32) Decimal {
//
func ParseDecimal(value string) (Decimal, error) {
var intString string
var exp int32
var exp = int32(0)
n := strings.IndexAny(value, "eE")
if n > 0 {
// It is scientific notation, like 3.14e10
expInt, err := strconv.Atoi(value[n+1:])
if err != nil {
return Decimal{}, fmt.Errorf("can't convert %s to decimal, incorrect exponent", value)
}
value = value[0:n]
exp = int32(expInt)
}
parts := strings.Split(value, ".")
if len(parts) == 1 {
// There is no decimal point, we can just parse the original string as
// an int.
intString = value
exp = 0
} else if len(parts) == 2 {
intString = parts[0] + parts[1]
expInt := -len(parts[1])
exp = int32(expInt)
exp += int32(expInt)
} else {
return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value)
}

View File

@ -869,3 +869,43 @@ func didPanic(f func()) bool {
return ret
}
func TestDecimalScientificNotation(t *testing.T) {
tbl := []struct {
Input string
Expected float64
}{
{"314e-2", 3.14},
{"1e2", 100},
{"2E-1", 0.2},
{"2E0", 2},
{"2.2E-1", 0.22},
}
for _, c := range tbl {
n, err := ParseDecimal(c.Input)
if err != nil {
t.Error(err)
}
f, _ := n.Float64()
if f != c.Expected {
t.Errorf("%f != %f", f, c.Expected)
}
}
tblErr := []string{
"12ee",
"ae10",
"12e1a",
"12e1.2",
"e1",
}
for _, c := range tblErr {
_, err := ParseDecimal(c)
if err == nil {
t.Errorf("%s must be invalid decimal", c)
}
}
}