for ; i < len(s); i++ {
switch {
case s[i] == '_':
- // underscoreOK already called
+ // readFloat already checked underscores
continue
case s[i] == '.':
if sawdot {
e := 0
for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
if s[i] == '_' {
- // underscoreOK already called
+ // readFloat already checked underscores
continue
}
if e < 10000 {
}
// readFloat reads a decimal mantissa and exponent from a float
-// string representation. It returns ok==false if the number could
-// not fit return types or is invalid.
+// string representation. It returns ok==false if the number
+// is invalid.
func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) {
i := 0
+ underscores := false
// optional sign
if i >= len(s) {
for ; i < len(s); i++ {
switch c := s[i]; true {
case c == '_':
- // underscoreOK already called
+ underscores = true
continue
case c == '.':
e := 0
for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
if s[i] == '_' {
- // underscoreOK already called
+ underscores = true
continue
}
if e < 10000 {
if mantissa != 0 {
exp = dp - ndMant
}
+
+ if underscores && !underscoreOK(s) {
+ return
+ }
+
ok = true
return
}
}
mantissa, exp, neg, trunc, hex, ok := readFloat(s)
- if hex && ok {
+ if !ok {
+ return 0, syntaxError(fnParseFloat, s)
+ }
+
+ if hex {
f, err := atofHex(s, &float32info, mantissa, exp, neg, trunc)
return float32(f), err
}
- if optimize && ok {
+ if optimize {
// Try pure floating-point arithmetic conversion.
if !trunc {
if f, ok := atof32exact(mantissa, exp, neg); ok {
}
mantissa, exp, neg, trunc, hex, ok := readFloat(s)
- if hex && ok {
+ if !ok {
+ return 0, syntaxError(fnParseFloat, s)
+ }
+
+ if hex {
return atofHex(s, &float64info, mantissa, exp, neg, trunc)
}
- if optimize && ok {
+ if optimize {
// Try pure floating-point arithmetic conversion.
if !trunc {
if f, ok := atof64exact(mantissa, exp, neg); ok {
// ParseFloat recognizes the strings "NaN", "+Inf", and "-Inf" as their
// respective special floating point values. It ignores case when matching.
func ParseFloat(s string, bitSize int) (float64, error) {
- if !underscoreOK(s) {
- return 0, syntaxError(fnParseFloat, s)
- }
if bitSize == 32 {
f, err := atof32(s)
return float64(f), err
func ParseUint(s string, base int, bitSize int) (uint64, error) {
const fnParseUint = "ParseUint"
- if s == "" || !underscoreOK(s) {
+ if s == "" {
return 0, syntaxError(fnParseUint, s)
}
maxVal := uint64(1)<<uint(bitSize) - 1
+ underscores := false
var n uint64
for _, c := range []byte(s) {
var d byte
switch {
case c == '_' && base0:
- // underscoreOK already called
+ underscores = true
continue
case '0' <= c && c <= '9':
d = c - '0'
n = n1
}
+ if underscores && !underscoreOK(s0) {
+ return 0, syntaxError(fnParseUint, s0)
+ }
+
return n, nil
}