diff --git a/json/strconv/atoi.go b/json/strconv/atoi.go index c1db0bd..546eae4 100644 --- a/json/strconv/atoi.go +++ b/json/strconv/atoi.go @@ -12,17 +12,16 @@ func lower(c byte) byte { return c | ('x' - 'X') } -const intSize = 32 << (^uint(0) >> 63) - -// IntSize is the size in bits of an int or uint value. -const IntSize = intSize - const maxUint64 = 1<<64 - 1 // ParseUint is like [ParseInt] but for unsigned numbers. // // A sign prefix is not permitted. -func ParseUint(s string, bitSize int) (uint64, error) { +func ParseUint(s string) (uint64, error) { + return parseUint(s, 64) +} + +func parseUint(s string, bitSize int) (uint64, error) { const fnParseUint = "ParseUint" base := 10 @@ -62,9 +61,7 @@ func ParseUint(s string, bitSize int) (uint64, error) { } if bitSize == 0 { - bitSize = IntSize - } else if bitSize < 0 || bitSize > 64 { - return 0, BitSizeError(fnParseUint, s0, bitSize) + bitSize = 64 } // Cutoff is the smallest number such that cutoff*base > maxUint64. @@ -147,7 +144,11 @@ func ParseUint(s string, bitSize int) (uint64, error) { // appropriate bitSize and sign. // // [integer literals]: https://go.dev/ref/spec#Integer_literals -func ParseInt(s string, bitSize int) (i int64, err error) { +func ParseInt(s string) (i int64, err error) { + return parseInt(s, 64) +} + +func parseInt(s string, bitSize int) (i int64, err error) { const fnParseInt = "ParseInt" if s == "" { @@ -166,14 +167,14 @@ func ParseInt(s string, bitSize int) (i int64, err error) { // Convert unsigned and check range. var un uint64 - un, err = ParseUint(s, bitSize) + un, err = parseUint(s, bitSize) if err != nil && err.(*NumError).Err != ErrRange { err.(*NumError).Func = fnParseInt return 0, err } if bitSize == 0 { - bitSize = IntSize + bitSize = 64 } cutoff := uint64(1 << uint(bitSize-1)) @@ -195,8 +196,7 @@ func Atoi(s string) (int, error) { const fnAtoi = "Atoi" sLen := len(s) - if intSize == 32 && (0 < sLen && sLen < 10) || - intSize == 64 && (0 < sLen && sLen < 19) { + if 0 < sLen && sLen < 19 { // Fast path for small integers that fit int type. s0 := s if s[0] == '-' || s[0] == '+' { @@ -221,7 +221,7 @@ func Atoi(s string) (int, error) { } // Slow path for invalid, big, or underscored integers. - i64, err := ParseInt(s, 0) + i64, err := parseInt(s, 0) if nerr, ok := err.(*NumError); ok { nerr.Func = fnAtoi } diff --git a/json/strconv/atoi_test.go b/json/strconv/atoi_test.go index 87b26d5..c40473a 100644 --- a/json/strconv/atoi_test.go +++ b/json/strconv/atoi_test.go @@ -361,7 +361,7 @@ func init() { func TestParseUint64(t *testing.T) { for i := range parseUint64Tests { test := &parseUint64Tests[i] - out, err := ParseUint(test.in, 64) + out, err := ParseUint(test.in) if test.out != out || !reflect.DeepEqual(test.err, err) { t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -372,7 +372,7 @@ func TestParseUint64(t *testing.T) { func TestParseInt64(t *testing.T) { for i := range parseInt64Tests { test := &parseInt64Tests[i] - out, err := ParseInt(test.in, 64) + out, err := ParseInt(test.in) if test.out != out || !reflect.DeepEqual(test.err, err) { t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -381,78 +381,38 @@ func TestParseInt64(t *testing.T) { } func TestParseUint(t *testing.T) { - switch IntSize { - case 32: - for i := range parseUint32Tests { - test := &parseUint32Tests[i] - out, err := ParseUint(test.in, 0) - if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v", - test.in, out, err, test.out, test.err) - } - } - case 64: - for i := range parseUint64Tests { - test := &parseUint64Tests[i] - out, err := ParseUint(test.in, 0) - if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v", - test.in, out, err, test.out, test.err) - } + for i := range parseUint64Tests { + test := &parseUint64Tests[i] + out, err := ParseUint(test.in) + if test.out != out || !reflect.DeepEqual(test.err, err) { + t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v", + test.in, out, err, test.out, test.err) } } } func TestParseInt(t *testing.T) { - switch IntSize { - case 32: - for i := range parseInt32Tests { - test := &parseInt32Tests[i] - out, err := ParseInt(test.in, 0) - if int64(test.out) != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v", - test.in, out, err, test.out, test.err) - } - } - case 64: - for i := range parseInt64Tests { - test := &parseInt64Tests[i] - out, err := ParseInt(test.in, 0) - if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v", - test.in, out, err, test.out, test.err) - } + for i := range parseInt64Tests { + test := &parseInt64Tests[i] + out, err := ParseInt(test.in) + if test.out != out || !reflect.DeepEqual(test.err, err) { + t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v", + test.in, out, err, test.out, test.err) } } } func TestAtoi(t *testing.T) { - switch IntSize { - case 32: - for i := range parseInt32Tests { - test := &parseInt32Tests[i] - out, err := Atoi(test.in) - var testErr error - if test.err != nil { - testErr = &NumError{"Atoi", test.err.(*NumError).Err} - } - if int(test.out) != out || !reflect.DeepEqual(testErr, err) { - t.Errorf("Atoi(%q) = %v, %v want %v, %v", - test.in, out, err, test.out, testErr) - } + for i := range parseInt64Tests { + test := &parseInt64Tests[i] + out, err := Atoi(test.in) + var testErr error + if test.err != nil { + testErr = &NumError{"Atoi", test.err.(*NumError).Err} } - case 64: - for i := range parseInt64Tests { - test := &parseInt64Tests[i] - out, err := Atoi(test.in) - var testErr error - if test.err != nil { - testErr = &NumError{"Atoi", test.err.(*NumError).Err} - } - if test.out != int64(out) || !reflect.DeepEqual(testErr, err) { - t.Errorf("Atoi(%q) = %v, %v want %v, %v", - test.in, out, err, test.out, testErr) - } + if test.out != int64(out) || !reflect.DeepEqual(testErr, err) { + t.Errorf("Atoi(%q) = %v, %v want %v, %v", + test.in, out, err, test.out, testErr) } } } @@ -487,30 +447,6 @@ func equalError(a, b error) bool { return a.Error() == b.Error() } -func TestParseIntBitSize(t *testing.T) { - for i := range parseBitSizeTests { - test := &parseBitSizeTests[i] - testErr := test.errStub("ParseInt", test.arg) - _, err := ParseInt("0", test.arg) - if !equalError(testErr, err) { - t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v", - test.arg, err, testErr) - } - } -} - -func TestParseUintBitSize(t *testing.T) { - for i := range parseBitSizeTests { - test := &parseBitSizeTests[i] - testErr := test.errStub("ParseUint", test.arg) - _, err := ParseUint("0", test.arg) - if !equalError(testErr, err) { - t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v", - test.arg, err, testErr) - } - } -} - func TestNumError(t *testing.T) { for _, test := range numErrorTests { err := &NumError{ @@ -556,7 +492,7 @@ func benchmarkParseInt(b *testing.B, neg int) { b.Run(cs.name, func(b *testing.B) { s := fmt.Sprintf("%d", cs.num*int64(neg)) for i := 0; i < b.N; i++ { - out, _ := ParseInt(s, 64) + out, _ := ParseInt(s) BenchSink += int(out) } }) @@ -578,12 +514,10 @@ func benchmarkAtoi(b *testing.B, neg int) { {"26bit", 1<<26 - 1}, {"31bit", 1<<31 - 1}, } - if IntSize == 64 { - cases = append(cases, []benchCase{ - {"56bit", 1<<56 - 1}, - {"63bit", 1<<63 - 1}, - }...) - } + cases = append(cases, []benchCase{ + {"56bit", 1<<56 - 1}, + {"63bit", 1<<63 - 1}, + }...) for _, cs := range cases { b.Run(cs.name, func(b *testing.B) { s := fmt.Sprintf("%d", cs.num*int64(neg))