// SetString sets z to the value of s and returns z and a boolean indicating
// success. s must be a floating-point number of the same format as accepted
-// by Scan, with number prefixes permitted.
+// by Parse, with base argument 0.
func (z *Float) SetString(s string) (*Float, bool) {
- r := strings.NewReader(s)
-
- f, _, err := z.Scan(r, 0)
- if err != nil {
- return nil, false
- }
-
- // there should be no unread characters left
- if _, err = r.ReadByte(); err != io.EOF {
- return nil, false
+ if f, _, err := z.Parse(s, 0); err == nil {
+ return f, true
}
-
- return f, true
+ return nil, false
}
-// Scan scans the number corresponding to the longest possible prefix
-// of r representing a floating-point number with a mantissa in the
-// given conversion base (the exponent is always a decimal number).
-// It sets z to the (possibly rounded) value of the corresponding
-// floating-point number, and returns z, the actual base b, and an
-// error err, if any. If z's precision is 0, it is changed to 64
-// before rounding takes effect. The number must be of the form:
-//
-// number = [ sign ] [ prefix ] mantissa [ exponent ] .
-// sign = "+" | "-" .
-// prefix = "0" ( "x" | "X" | "b" | "B" ) .
-// mantissa = digits | digits "." [ digits ] | "." digits .
-// exponent = ( "E" | "e" | "p" ) [ sign ] digits .
-// digits = digit { digit } .
-// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
-//
-// The base argument must be 0, 2, 10, or 16. Providing an invalid base
-// argument will lead to a run-time panic.
-//
-// For base 0, the number prefix determines the actual base: A prefix of
-// "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects
-// base 2; otherwise, the actual base is 10 and no prefix is accepted.
-// The octal prefix "0" is not supported (a leading "0" is simply
-// considered a "0").
-//
-// A "p" exponent indicates a binary (rather then decimal) exponent;
-// for instance "0x1.fffffffffffffp1023" (using base 0) represents the
-// maximum float64 value. For hexadecimal mantissae, the exponent must
-// be binary, if present (an "e" or "E" exponent indicator cannot be
-// distinguished from a mantissa digit).
-//
-// The returned *Float f is nil and the value of z is valid but not
-// defined if an error is reported.
-//
-// BUG(gri) The Float.Scan signature conflicts with Scan(s fmt.ScanState, ch rune) error.
-// (https://github.com/golang/go/issues/10938)
-func (z *Float) Scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
+// scan is like Parse but reads the longest possible prefix representing a valid
+// floating point number from an io.ByteScanner rather than a string. It serves
+// as the implementation of Parse. It does not recognize ±Inf and does not expect
+// EOF at the end.
+func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
prec := z.prec
if prec == 0 {
prec = 64
return z
}
-// Parse is like z.Scan(r, base), but instead of reading from an
-// io.ByteScanner, it parses the string s. An error is also returned
-// if the string contains invalid or trailing bytes not belonging to
-// the number.
+// Parse parses s which must contain a text representation of a floating-
+// point number with a mantissa in the given conversion base (the exponent
+// is always a decimal number), or a string representing an infinite value.
+//
+// It sets z to the (possibly rounded) value of the corresponding floating-
+// point value, and returns z, the actual base b, and an error err, if any.
+// If z's precision is 0, it is changed to 64 before rounding takes effect.
+// The number must be of the form:
+//
+// number = [ sign ] [ prefix ] mantissa [ exponent ] | infinity .
+// sign = "+" | "-" .
+// prefix = "0" ( "x" | "X" | "b" | "B" ) .
+// mantissa = digits | digits "." [ digits ] | "." digits .
+// exponent = ( "E" | "e" | "p" ) [ sign ] digits .
+// digits = digit { digit } .
+// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
+// infinity = [ sign ] ( "inf" | "Inf" ) .
+//
+// The base argument must be 0, 2, 10, or 16. Providing an invalid base
+// argument will lead to a run-time panic.
+//
+// For base 0, the number prefix determines the actual base: A prefix of
+// "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects
+// base 2; otherwise, the actual base is 10 and no prefix is accepted.
+// The octal prefix "0" is not supported (a leading "0" is simply
+// considered a "0").
+//
+// A "p" exponent indicates a binary (rather then decimal) exponent;
+// for instance "0x1.fffffffffffffp1023" (using base 0) represents the
+// maximum float64 value. For hexadecimal mantissae, the exponent must
+// be binary, if present (an "e" or "E" exponent indicator cannot be
+// distinguished from a mantissa digit).
+//
+// The returned *Float f is nil and the value of z is valid but not
+// defined if an error is reported.
+//
func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
- r := strings.NewReader(s)
+ // scan doesn't handle ±Inf
+ if len(s) == 3 && (s == "Inf" || s == "inf") {
+ f = z.SetInf(false)
+ return
+ }
+ if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") {
+ f = z.SetInf(s[0] == '-')
+ return
+ }
- if f, b, err = z.Scan(r, base); err != nil {
+ r := strings.NewReader(s)
+ if f, b, err = z.scan(r, base); err != nil {
return
}
return
}
-// ScanFloat is like f.Scan(r, base) with f set to the given precision
-// and rounding mode.
-func ScanFloat(r io.ByteScanner, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
- return new(Float).SetPrec(prec).SetMode(mode).Scan(r, base)
-}
-
// ParseFloat is like f.Parse(s, base) with f set to the given precision
// and rounding mode.
func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {