Add scientific notation parsing

This commit is contained in:
Thiago Arruda 2015-07-24 13:16:41 -03:00
parent 6da60a24bd
commit 849f553b9d
2 changed files with 37 additions and 2 deletions

View file

@ -82,12 +82,23 @@ func New(value int64, exp int32) Decimal {
func NewFromString(value string) (Decimal, error) {
var intString string
var exp int32
// Check if number is using scientific notation
eIndex := strings.IndexAny(value, "Ee")
if eIndex != -1 {
expInt, err := strconv.ParseInt(value[eIndex+1:len(value)], 10, 32)
if err != nil {
return Decimal{}, fmt.Errorf("can't convert %s to decimal: exponent is not numeric", value)
}
value = value[0:eIndex]
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])
@ -95,7 +106,7 @@ func NewFromString(value string) (Decimal, error) {
// NOTE(vadim): I doubt a string could realistically be this long
return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", value)
}
exp = int32(expInt)
exp += int32(expInt)
} else {
return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value)
}

View file

@ -32,6 +32,16 @@ var testTable = map[float64]string{
.1000000000000008: "0.1000000000000008",
}
var testTableScientificNotation = map[string]string{
"1e9": "1000000000",
"2.41E-3": "0.00241",
"24.2E-4": "0.00242",
"243E-5": "0.00243",
"-1e-5": "-0.00001",
"-245E3": "-245000",
"1.2345E-1": "0.12345",
}
func init() {
// add negatives
for f, s := range testTable {
@ -76,6 +86,17 @@ func TestNewFromString(t *testing.T) {
d.value.String(), d.exp)
}
}
for e, s := range testTableScientificNotation {
d, err := NewFromString(e)
if err != nil {
t.Errorf("error while parsing %s", e)
} else if d.String() != s {
t.Errorf("expected %s, got %s (%s, %d)",
s, d.String(),
d.value.String(), d.exp)
}
}
}
func TestNewFromStringErrs(t *testing.T) {
@ -95,6 +116,9 @@ func TestNewFromStringErrs(t *testing.T) {
".5.2",
"8..2",
"8.1.",
"1e",
"1-e",
"1e9e",
}
for _, s := range tests {