github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/gc/big/floatconv.go (about)

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