]> Cypherpunks repositories - gostls13.git/commitdiff
fmt.Scan: scan binary-exponent floating format, 2.4p-3
authorRob Pike <r@golang.org>
Wed, 2 Feb 2011 20:38:48 +0000 (12:38 -0800)
committerRob Pike <r@golang.org>
Wed, 2 Feb 2011 20:38:48 +0000 (12:38 -0800)
R=rsc, rog, r2
CC=golang-dev
https://golang.org/cl/4128049

src/pkg/fmt/scan.go
src/pkg/fmt/scan_test.go

index a408c42aaf1b623341b1e77f86368fd61c49121c..224293da2689f0183cb9ce5d1b008c490184394a 100644 (file)
@@ -7,6 +7,7 @@ package fmt
 import (
        "bytes"
        "io"
+       "math"
        "os"
        "reflect"
        "strconv"
@@ -459,7 +460,7 @@ const (
        hexadecimalDigits = "0123456789aAbBcCdDeEfF"
        sign              = "+-"
        period            = "."
-       exponent          = "eE"
+       exponent          = "eEp"
 )
 
 // getBase returns the numeric base represented by the verb and its digit string.
@@ -617,6 +618,27 @@ func (s *ss) complexTokens() (real, imag string) {
 
 // convertFloat converts the string to a float64value.
 func (s *ss) convertFloat(str string, n int) float64 {
+       if p := strings.Index(str, "p"); p >= 0 {
+               // Atof doesn't handle power-of-2 exponents,
+               // but they're easy to evaluate.
+               f, err := strconv.AtofN(str[:p], n)
+               if err != nil {
+                       // Put full string into error.
+                       if e, ok := err.(*strconv.NumError); ok {
+                               e.Num = str
+                       }
+                       s.error(err)
+               }
+               n, err := strconv.Atoi(str[p+1:])
+               if err != nil {
+                       // Put full string into error.
+                       if e, ok := err.(*strconv.NumError); ok {
+                               e.Num = str
+                       }
+                       s.error(err)
+               }
+               return math.Ldexp(f, n)
+       }
        f, err := strconv.AtofN(str, n)
        if err != nil {
                s.error(err)
@@ -747,7 +769,7 @@ func (s *ss) hexString() string {
        return s.buf.String()
 }
 
-const floatVerbs = "eEfFgGv"
+const floatVerbs = "beEfFgGv"
 
 // scanOne scans a single value, deriving the scanner from the type of the argument.
 func (s *ss) scanOne(verb int, field interface{}) {
index 78b9fbb4ab06275fa26ecc6ac4d26ef678a645bf..c647fc7b5dec3b0f252d3b23aae4f685671a913b 100644 (file)
@@ -160,6 +160,10 @@ var scanTests = []ScanTest{
        {"2.3\n", &float64Val, 2.3},
        {"2.3e1\n", &float32Val, float32(2.3e1)},
        {"2.3e2\n", &float64Val, 2.3e2},
+       {"2.3p2\n", &float64Val, 2.3 * 4},
+       {"2.3p+2\n", &float64Val, 2.3 * 4},
+       {"2.3p+66\n", &float64Val, 2.3 * (1 << 32) * (1 << 32) * 4},
+       {"2.3p-66\n", &float64Val, 2.3 / ((1 << 32) * (1 << 32) * 4)},
        {"2.35\n", &stringVal, "2.35"},
        {"2345678\n", &bytesVal, []byte("2345678")},
        {"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i},