...

# Source file src/math/big/floatconv.go

```     1	// Copyright 2015 The Go Authors. All rights reserved.
2	// Use of this source code is governed by a BSD-style
4
5	// This file implements string-to-Float conversion functions.
6
7	package big
8
9	import (
10		"fmt"
11		"io"
12		"strings"
13	)
14
15	var floatZero Float
16
17	// SetString sets z to the value of s and returns z and a boolean indicating
18	// success. s must be a floating-point number of the same format as accepted
19	// by Parse, with base argument 0. The entire string (not just a prefix) must
20	// be valid for success. If the operation failed, the value of z is undefined
21	// but the returned value is nil.
22	func (z *Float) SetString(s string) (*Float, bool) {
23		if f, _, err := z.Parse(s, 0); err == nil {
24			return f, true
25		}
26		return nil, false
27	}
28
29	// scan is like Parse but reads the longest possible prefix representing a valid
30	// floating point number from an io.ByteScanner rather than a string. It serves
31	// as the implementation of Parse. It does not recognize ±Inf and does not expect
32	// EOF at the end.
33	func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
34		prec := z.prec
35		if prec == 0 {
36			prec = 64
37		}
38
39		// A reasonable value in case of an error.
40		z.form = zero
41
42		// sign
43		z.neg, err = scanSign(r)
44		if err != nil {
45			return
46		}
47
48		// mantissa
49		var fcount int // fractional digit count; valid if <= 0
50		z.mant, b, fcount, err = z.mant.scan(r, base, true)
51		if err != nil {
52			return
53		}
54
55		// exponent
56		var exp int64
57		var ebase int
58		exp, ebase, err = scanExponent(r, true)
59		if err != nil {
60			return
61		}
62
63		// special-case 0
64		if len(z.mant) == 0 {
65			z.prec = prec
66			z.acc = Exact
67			z.form = zero
68			f = z
69			return
70		}
71		// len(z.mant) > 0
72
73		// The mantissa may have a decimal point (fcount <= 0) and there
74		// may be a nonzero exponent exp. The decimal point amounts to a
75		// division by b**(-fcount). An exponent means multiplication by
76		// ebase**exp. Finally, mantissa normalization (shift left) requires
77		// a correcting multiplication by 2**(-shiftcount). Multiplications
78		// are commutative, so we can apply them in any order as long as there
79		// is no loss of precision. We only have powers of 2 and 10, and
80		// we split powers of 10 into the product of the same powers of
81		// 2 and 5. This reduces the size of the multiplication factor
82		// needed for base-10 exponents.
83
84		// normalize mantissa and determine initial exponent contributions
85		exp2 := int64(len(z.mant))*_W - fnorm(z.mant)
86		exp5 := int64(0)
87
88		// determine binary or decimal exponent contribution of decimal point
89		if fcount < 0 {
90			// The mantissa has a "decimal" point ddd.dddd; and
91			// -fcount is the number of digits to the right of '.'.
92			// Adjust relevant exponent accordingly.
93			d := int64(fcount)
94			switch b {
95			case 10:
96				exp5 = d
97				fallthrough // 10**e == 5**e * 2**e
98			case 2:
99				exp2 += d
100			case 16:
101				exp2 += d * 4 // hexadecimal digits are 4 bits each
102			default:
103				panic("unexpected mantissa base")
104			}
105			// fcount consumed - not needed anymore
106		}
107
108		// take actual exponent into account
109		switch ebase {
110		case 10:
111			exp5 += exp
112			fallthrough
113		case 2:
114			exp2 += exp
115		default:
116			panic("unexpected exponent base")
117		}
118		// exp consumed - not needed anymore
119
120		// apply 2**exp2
121		if MinExp <= exp2 && exp2 <= MaxExp {
122			z.prec = prec
123			z.form = finite
124			z.exp = int32(exp2)
125			f = z
126		} else {
127			err = fmt.Errorf("exponent overflow")
128			return
129		}
130
131		if exp5 == 0 {
132			// no decimal exponent contribution
133			z.round(0)
134			return
135		}
136		// exp5 != 0
137
138		// apply 5**exp5
139		p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number?
140		if exp5 < 0 {
141			z.Quo(z, p.pow5(uint64(-exp5)))
142		} else {
143			z.Mul(z, p.pow5(uint64(exp5)))
144		}
145
146		return
147	}
148
149	// These powers of 5 fit into a uint64.
150	//
151	//	for p, q := uint64(0), uint64(1); p < q; p, q = q, q*5 {
152	//		fmt.Println(q)
153	//	}
154	//
155	var pow5tab = [...]uint64{
156		1,
157		5,
158		25,
159		125,
160		625,
161		3125,
162		15625,
163		78125,
164		390625,
165		1953125,
166		9765625,
167		48828125,
168		244140625,
169		1220703125,
170		6103515625,
171		30517578125,
172		152587890625,
173		762939453125,
174		3814697265625,
175		19073486328125,
176		95367431640625,
177		476837158203125,
178		2384185791015625,
179		11920928955078125,
180		59604644775390625,
181		298023223876953125,
182		1490116119384765625,
183		7450580596923828125,
184	}
185
186	// pow5 sets z to 5**n and returns z.
187	// n must not be negative.
188	func (z *Float) pow5(n uint64) *Float {
189		const m = uint64(len(pow5tab) - 1)
190		if n <= m {
191			return z.SetUint64(pow5tab[n])
192		}
193		// n > m
194
195		z.SetUint64(pow5tab[m])
196		n -= m
197
198		// use more bits for f than for z
199		// TODO(gri) what is the right number?
200		f := new(Float).SetPrec(z.Prec() + 64).SetUint64(5)
201
202		for n > 0 {
203			if n&1 != 0 {
204				z.Mul(z, f)
205			}
206			f.Mul(f, f)
207			n >>= 1
208		}
209
210		return z
211	}
212
213	// Parse parses s which must contain a text representation of a floating-
214	// point number with a mantissa in the given conversion base (the exponent
215	// is always a decimal number), or a string representing an infinite value.
216	//
217	// It sets z to the (possibly rounded) value of the corresponding floating-
218	// point value, and returns z, the actual base b, and an error err, if any.
219	// The entire string (not just a prefix) must be consumed for success.
220	// If z's precision is 0, it is changed to 64 before rounding takes effect.
221	// The number must be of the form:
222	//
223	//	number   = [ sign ] [ prefix ] mantissa [ exponent ] | infinity .
224	//	sign     = "+" | "-" .
225	//	prefix   = "0" ( "x" | "X" | "b" | "B" ) .
226	//	mantissa = digits | digits "." [ digits ] | "." digits .
227	//	exponent = ( "E" | "e" | "p" ) [ sign ] digits .
228	//	digits   = digit { digit } .
229	//	digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
230	//	infinity = [ sign ] ( "inf" | "Inf" ) .
231	//
232	// The base argument must be 0, 2, 10, or 16. Providing an invalid base
233	// argument will lead to a run-time panic.
234	//
235	// For base 0, the number prefix determines the actual base: A prefix of
236	// "0x" or "0X" selects base 16, and a "0b" or "0B" prefix selects
237	// base 2; otherwise, the actual base is 10 and no prefix is accepted.
238	// The octal prefix "0" is not supported (a leading "0" is simply
239	// considered a "0").
240	//
241	// A "p" exponent indicates a binary (rather then decimal) exponent;
242	// for instance "0x1.fffffffffffffp1023" (using base 0) represents the
243	// maximum float64 value. For hexadecimal mantissae, the exponent must
244	// be binary, if present (an "e" or "E" exponent indicator cannot be
245	// distinguished from a mantissa digit).
246	//
247	// The returned *Float f is nil and the value of z is valid but not
248	// defined if an error is reported.
249	//
250	func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
251		// scan doesn't handle ±Inf
252		if len(s) == 3 && (s == "Inf" || s == "inf") {
253			f = z.SetInf(false)
254			return
255		}
256		if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") {
257			f = z.SetInf(s[0] == '-')
258			return
259		}
260
262		if f, b, err = z.scan(r, base); err != nil {
263			return
264		}
265
266		// entire string must have been consumed
267		if ch, err2 := r.ReadByte(); err2 == nil {
268			err = fmt.Errorf("expected end of string, found %q", ch)
269		} else if err2 != io.EOF {
270			err = err2
271		}
272
273		return
274	}
275
276	// ParseFloat is like f.Parse(s, base) with f set to the given precision
277	// and rounding mode.
278	func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
279		return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base)
280	}
281
282	var _ fmt.Scanner = &floatZero // *Float must implement fmt.Scanner
283
284	// Scan is a support routine for fmt.Scanner; it sets z to the value of
285	// the scanned number. It accepts formats whose verbs are supported by
286	// fmt.Scan for floating point values, which are:
287	// 'b' (binary), 'e', 'E', 'f', 'F', 'g' and 'G'.
288	// Scan doesn't handle ±Inf.
289	func (z *Float) Scan(s fmt.ScanState, ch rune) error {
290		s.SkipSpace()
291		_, _, err := z.scan(byteReader{s}, 0)
292		return err
293	}
294
```

View as plain text