github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/math/big/floatconv.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file implements float-to-string conversion functions.
     6  
     7  package big
     8  
     9  import (
    10  	"fmt"
    11  	"io"
    12  	"strconv"
    13  	"strings"
    14  )
    15  
    16  // SetString sets z to the value of s and returns z and a boolean indicating
    17  // success. s must be a floating-point number of the same format as accepted
    18  // by Scan, with number prefixes permitted.
    19  func (z *Float) SetString(s string) (*Float, bool) {
    20  	r := strings.NewReader(s)
    21  
    22  	f, _, err := z.Scan(r, 0)
    23  	if err != nil {
    24  		return nil, false
    25  	}
    26  
    27  	// there should be no unread characters left
    28  	if _, err = r.ReadByte(); err != io.EOF {
    29  		return nil, false
    30  	}
    31  
    32  	return f, true
    33  }
    34  
    35  // Scan scans the number corresponding to the longest possible prefix
    36  // of r representing a floating-point number with a mantissa in the
    37  // given conversion base (the exponent is always a decimal number).
    38  // It sets z to the (possibly rounded) value of the corresponding
    39  // floating-point number, and returns z, the actual base b, and an
    40  // error err, if any. If z's precision is 0, it is changed to 64
    41  // before rounding takes effect. The number must be of the form:
    42  //
    43  //	number   = [ sign ] [ prefix ] mantissa [ exponent ] .
    44  //	sign     = "+" | "-" .
    45  //      prefix   = "0" ( "x" | "X" | "b" | "B" ) .
    46  //	mantissa = digits | digits "." [ digits ] | "." digits .
    47  //	exponent = ( "E" | "e" | "p" ) [ sign ] digits .
    48  //	digits   = digit { digit } .
    49  //	digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
    50  //
    51  // The base argument must be 0, 2, 10, or 16. Providing an invalid base
    52  // argument will lead to a run-time panic.
    53  //
    54  // For base 0, the number prefix determines the actual base: A prefix of
    55  // "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects
    56  // base 2; otherwise, the actual base is 10 and no prefix is accepted.
    57  // The octal prefix "0" is not supported (a leading "0" is simply
    58  // considered a "0").
    59  //
    60  // A "p" exponent indicates a binary (rather then decimal) exponent;
    61  // for instance "0x1.fffffffffffffp1023" (using base 0) represents the
    62  // maximum float64 value. For hexadecimal mantissae, the exponent must
    63  // be binary, if present (an "e" or "E" exponent indicator cannot be
    64  // distinguished from a mantissa digit).
    65  //
    66  // The returned *Float f is nil and the value of z is valid but not
    67  // defined if an error is reported.
    68  //
    69  // BUG(gri) The Float.Scan signature conflicts with Scan(s fmt.ScanState, ch rune) error.
    70  func (z *Float) Scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
    71  	prec := z.prec
    72  	if prec == 0 {
    73  		prec = 64
    74  	}
    75  
    76  	// A reasonable value in case of an error.
    77  	z.form = zero
    78  
    79  	// sign
    80  	z.neg, err = scanSign(r)
    81  	if err != nil {
    82  		return
    83  	}
    84  
    85  	// mantissa
    86  	var fcount int // fractional digit count; valid if <= 0
    87  	z.mant, b, fcount, err = z.mant.scan(r, base, true)
    88  	if err != nil {
    89  		return
    90  	}
    91  
    92  	// exponent
    93  	var exp int64
    94  	var ebase int
    95  	exp, ebase, err = scanExponent(r, true)
    96  	if err != nil {
    97  		return
    98  	}
    99  
   100  	// special-case 0
   101  	if len(z.mant) == 0 {
   102  		z.prec = prec
   103  		z.acc = Exact
   104  		z.form = zero
   105  		f = z
   106  		return
   107  	}
   108  	// len(z.mant) > 0
   109  
   110  	// The mantissa may have a decimal point (fcount <= 0) and there
   111  	// may be a nonzero exponent exp. The decimal point amounts to a
   112  	// division by b**(-fcount). An exponent means multiplication by
   113  	// ebase**exp. Finally, mantissa normalization (shift left) requires
   114  	// a correcting multiplication by 2**(-shiftcount). Multiplications
   115  	// are commutative, so we can apply them in any order as long as there
   116  	// is no loss of precision. We only have powers of 2 and 10; keep
   117  	// track via separate exponents exp2 and exp10.
   118  
   119  	// normalize mantissa and get initial binary exponent
   120  	var exp2 = int64(len(z.mant))*_W - fnorm(z.mant)
   121  
   122  	// determine binary or decimal exponent contribution of decimal point
   123  	var exp10 int64
   124  	if fcount < 0 {
   125  		// The mantissa has a "decimal" point ddd.dddd; and
   126  		// -fcount is the number of digits to the right of '.'.
   127  		// Adjust relevant exponent accodingly.
   128  		switch b {
   129  		case 16:
   130  			fcount *= 4 // hexadecimal digits are 4 bits each
   131  			fallthrough
   132  		case 2:
   133  			exp2 += int64(fcount)
   134  		default: // b == 10
   135  			exp10 = int64(fcount)
   136  		}
   137  		// we don't need fcount anymore
   138  	}
   139  
   140  	// take actual exponent into account
   141  	if ebase == 2 {
   142  		exp2 += exp
   143  	} else { // ebase == 10
   144  		exp10 += exp
   145  	}
   146  	// we don't need exp anymore
   147  
   148  	// apply 2**exp2
   149  	if MinExp <= exp2 && exp2 <= MaxExp {
   150  		z.prec = prec
   151  		z.form = finite
   152  		z.exp = int32(exp2)
   153  		f = z
   154  	} else {
   155  		err = fmt.Errorf("exponent overflow")
   156  		return
   157  	}
   158  
   159  	if exp10 == 0 {
   160  		// no decimal exponent to consider
   161  		z.round(0)
   162  		return
   163  	}
   164  	// exp10 != 0
   165  
   166  	// apply 10**exp10
   167  	p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number?
   168  	if exp10 < 0 {
   169  		z.uquo(z, p.pow10(-exp10))
   170  	} else {
   171  		z.umul(z, p.pow10(exp10))
   172  	}
   173  
   174  	return
   175  }
   176  
   177  // These powers of 10 can be represented exactly as a float64.
   178  var pow10tab = [...]float64{
   179  	1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
   180  	1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
   181  }
   182  
   183  // pow10 sets z to 10**n and returns z.
   184  // n must not be negative.
   185  func (z *Float) pow10(n int64) *Float {
   186  	if n < 0 {
   187  		panic("pow10 called with negative argument")
   188  	}
   189  
   190  	const m = int64(len(pow10tab) - 1)
   191  	if n <= m {
   192  		return z.SetFloat64(pow10tab[n])
   193  	}
   194  	// n > m
   195  
   196  	z.SetFloat64(pow10tab[m])
   197  	n -= m
   198  
   199  	// use more bits for f than for z
   200  	// TODO(gri) what is the right number?
   201  	f := new(Float).SetPrec(z.Prec() + 64).SetInt64(10)
   202  
   203  	for n > 0 {
   204  		if n&1 != 0 {
   205  			z.Mul(z, f)
   206  		}
   207  		f.Mul(f, f)
   208  		n >>= 1
   209  	}
   210  
   211  	return z
   212  }
   213  
   214  // Parse is like z.Scan(r, base), but instead of reading from an
   215  // io.ByteScanner, it parses the string s. An error is also returned
   216  // if the string contains invalid or trailing bytes not belonging to
   217  // the number.
   218  func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
   219  	r := strings.NewReader(s)
   220  
   221  	if f, b, err = z.Scan(r, base); err != nil {
   222  		return
   223  	}
   224  
   225  	// entire string must have been consumed
   226  	if ch, err2 := r.ReadByte(); err2 == nil {
   227  		err = fmt.Errorf("expected end of string, found %q", ch)
   228  	} else if err2 != io.EOF {
   229  		err = err2
   230  	}
   231  
   232  	return
   233  }
   234  
   235  // ScanFloat is like f.Scan(r, base) with f set to the given precision
   236  // and rounding mode.
   237  func ScanFloat(r io.ByteScanner, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
   238  	return new(Float).SetPrec(prec).SetMode(mode).Scan(r, base)
   239  }
   240  
   241  // ParseFloat is like f.Parse(s, base) with f set to the given precision
   242  // and rounding mode.
   243  func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
   244  	return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base)
   245  }
   246  
   247  // Format converts the floating-point number x to a string according
   248  // to the given format and precision prec. The format is one of:
   249  //
   250  //	'e'	-d.dddde±dd, decimal exponent, at least two (possibly 0) exponent digits
   251  //	'E'	-d.ddddE±dd, decimal exponent, at least two (possibly 0) exponent digits
   252  //	'f'	-ddddd.dddd, no exponent
   253  //	'g'	like 'e' for large exponents, like 'f' otherwise
   254  //	'G'	like 'E' for large exponents, like 'f' otherwise
   255  //	'b'	-ddddddp±dd, binary exponent
   256  //	'p'	-0x.dddp±dd, binary exponent, hexadecimal mantissa
   257  //
   258  // For the binary exponent formats, the mantissa is printed in normalized form:
   259  //
   260  //	'b'	decimal integer mantissa using x.Prec() bits, or -0
   261  //	'p'	hexadecimal fraction with 0.5 <= 0.mantissa < 1.0, or -0
   262  //
   263  // The precision prec controls the number of digits (excluding the exponent)
   264  // printed by the 'e', 'E', 'f', 'g', and 'G' formats. For 'e', 'E', and 'f'
   265  // it is the number of digits after the decimal point. For 'g' and 'G' it is
   266  // the total number of digits. A negative precision selects the smallest
   267  // number of digits necessary such that ParseFloat will return f exactly.
   268  // The prec value is ignored for the 'b' or 'p' format.
   269  //
   270  // BUG(gri) Float.Format does not accept negative precisions.
   271  func (x *Float) Format(format byte, prec int) string {
   272  	const extra = 10 // TODO(gri) determine a good/better value here
   273  	return string(x.Append(make([]byte, 0, prec+extra), format, prec))
   274  }
   275  
   276  // Append appends the string form of the floating-point number x,
   277  // as generated by x.Format, to buf and returns the extended buffer.
   278  func (x *Float) Append(buf []byte, format byte, prec int) []byte {
   279  	// TODO(gri) factor out handling of sign?
   280  
   281  	// Inf
   282  	if x.IsInf() {
   283  		var ch byte = '+'
   284  		if x.neg {
   285  			ch = '-'
   286  		}
   287  		buf = append(buf, ch)
   288  		return append(buf, "Inf"...)
   289  	}
   290  
   291  	// easy formats
   292  	switch format {
   293  	case 'b':
   294  		return x.bstring(buf)
   295  	case 'p':
   296  		return x.pstring(buf)
   297  	}
   298  
   299  	return x.bigFtoa(buf, format, prec)
   300  }
   301  
   302  // BUG(gri): Float.String uses x.Format('g', 10) rather than x.Format('g', -1).
   303  func (x *Float) String() string {
   304  	return x.Format('g', 10)
   305  }
   306  
   307  // bstring appends the string of x in the format ["-"] mantissa "p" exponent
   308  // with a decimal mantissa and a binary exponent, or ["-"] "0" if x is zero,
   309  // and returns the extended buffer.
   310  // The mantissa is normalized such that is uses x.Prec() bits in binary
   311  // representation.
   312  func (x *Float) bstring(buf []byte) []byte {
   313  	if x.neg {
   314  		buf = append(buf, '-')
   315  	}
   316  	if x.form == zero {
   317  		return append(buf, '0')
   318  	}
   319  
   320  	if debugFloat && x.form != finite {
   321  		panic("non-finite float")
   322  	}
   323  	// x != 0
   324  
   325  	// adjust mantissa to use exactly x.prec bits
   326  	m := x.mant
   327  	switch w := uint32(len(x.mant)) * _W; {
   328  	case w < x.prec:
   329  		m = nat(nil).shl(m, uint(x.prec-w))
   330  	case w > x.prec:
   331  		m = nat(nil).shr(m, uint(w-x.prec))
   332  	}
   333  
   334  	buf = append(buf, m.decimalString()...)
   335  	buf = append(buf, 'p')
   336  	e := int64(x.exp) - int64(x.prec)
   337  	if e >= 0 {
   338  		buf = append(buf, '+')
   339  	}
   340  	return strconv.AppendInt(buf, e, 10)
   341  }
   342  
   343  // pstring appends the string of x in the format ["-"] "0x." mantissa "p" exponent
   344  // with a hexadecimal mantissa and a binary exponent, or ["-"] "0" if x is zero,
   345  // ad returns the extended buffer.
   346  // The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0.
   347  func (x *Float) pstring(buf []byte) []byte {
   348  	if x.neg {
   349  		buf = append(buf, '-')
   350  	}
   351  	if x.form == zero {
   352  		return append(buf, '0')
   353  	}
   354  
   355  	if debugFloat && x.form != finite {
   356  		panic("non-finite float")
   357  	}
   358  	// x != 0
   359  
   360  	// remove trailing 0 words early
   361  	// (no need to convert to hex 0's and trim later)
   362  	m := x.mant
   363  	i := 0
   364  	for i < len(m) && m[i] == 0 {
   365  		i++
   366  	}
   367  	m = m[i:]
   368  
   369  	buf = append(buf, "0x."...)
   370  	buf = append(buf, strings.TrimRight(x.mant.hexString(), "0")...)
   371  	buf = append(buf, 'p')
   372  	return strconv.AppendInt(buf, int64(x.exp), 10)
   373  }