Skip to content

fastfloat: strconv inequivalence - ParseFloat64("8.54E-4") got = 0.0008539999999999999, want 0.000854 #91

@mattburman

Description

@mattburman

Hi

Is it possible to maintain equivalence with strconv for values like 8.54E-4?

diff --git a/fastfloat/parse_test.go b/fastfloat/parse_test.go
index e4dfe2f..28dfecd 100644
--- a/fastfloat/parse_test.go
+++ b/fastfloat/parse_test.go
@@ -445,6 +445,7 @@ func TestParseSuccess(t *testing.T) {
 	f("-123e456", math.Inf(-1)) // too big exponent
 	f("1e4", 1e4)
 	f("-1E-10", -1e-10)
+	f("8.54E-4", 8.54e-4)
 
 	// Fractional + exponent part
 	f("0.123e4", 0.123e4)
$ go test ./... 
--- FAIL: TestParseSuccess (0.00s)
    parse_test.go:448: unexpected number parsed from "8.54E-4"; got 0.0008539999999999999; want 0.000854
FAIL
FAIL	github.com/valyala/fastjson/fastfloat	0.919s
FAIL
=== RUN   TestParseFloat64
=== RUN   TestParseFloat64/#04
    x_test.go:31: ParseFloat64("8.54E-4") got = 0.0008539999999999999, want 0.000854
    x_test.go:38: strconv.ParseFloat("8.54E-4") = 0.000854, fastfloat.ParseFloat64("8.54E-4") = 0.0008539999999999999
--- FAIL: TestParseFloat64 (0.00s)
    --- FAIL: TestParseFloat64/#04 (0.00s)


FAIL
import (
	"strconv"
	"testing"

	"github.com/valyala/fastjson/fastfloat"
)

func TestParseFloat64(t *testing.T) {
	tests := []struct {
		name    string
		in      string
		want    float64
		wantErr bool
	}{
		{"", "1.2", 1.2, false},
		{"", "1.3", 1.3, false},
		{"", "0.00077", 0.00077, false},
		{"", `0.000854`, 0.000854, false},
		{"", `8.54E-4`, 0.000854, false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, err := fastfloat.Parse(tt.in)
			if (err != nil) != tt.wantErr {
				t.Errorf("ParseFloat64() error = %v, wantErr %v", err, tt.wantErr)
				return
			}
			if got != tt.want {
				t.Errorf("ParseFloat64() got = %f, want %v", got, tt.want)
			}

			stdGot, _ := strconv.ParseFloat(tt.in, 64)
			if stdGot != got {
				t.Errorf(
					"strconv.ParseFloat() = %f, fastfloat.ParseFloat64() = %v",
					stdGot, got,
				)
			}
		})
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions