...

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

## Documentation: math/big

```     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 int-to-string conversion functions.
6
7  package big
8
9  import (
10  	"errors"
11  	"fmt"
12  	"io"
13  )
14
15  // Text returns the string representation of x in the given base.
16  // Base must be between 2 and 62, inclusive. The result uses the
17  // lower-case letters 'a' to 'z' for digit values 10 to 35, and
18  // the upper-case letters 'A' to 'Z' for digit values 36 to 61.
19  // No prefix (such as "0x") is added to the string.
20  func (x *Int) Text(base int) string {
21  	if x == nil {
22  		return "<nil>"
23  	}
24  	return string(x.abs.itoa(x.neg, base))
25  }
26
27  // Append appends the string representation of x, as generated by
28  // x.Text(base), to buf and returns the extended buffer.
29  func (x *Int) Append(buf []byte, base int) []byte {
30  	if x == nil {
31  		return append(buf, "<nil>"...)
32  	}
33  	return append(buf, x.abs.itoa(x.neg, base)...)
34  }
35
36  func (x *Int) String() string {
37  	return x.Text(10)
38  }
39
40  // write count copies of text to s
41  func writeMultiple(s fmt.State, text string, count int) {
42  	if len(text) > 0 {
43  		b := []byte(text)
44  		for ; count > 0; count-- {
45  			s.Write(b)
46  		}
47  	}
48  }
49
50  var _ fmt.Formatter = intOne // *Int must implement fmt.Formatter
51
52  // Format implements fmt.Formatter. It accepts the formats
53  // 'b' (binary), 'o' (octal), 'd' (decimal), 'x' (lowercase
55  // Also supported are the full suite of package fmt's format
56  // flags for integral types, including '+' and ' ' for sign
57  // control, '#' for leading zero in octal and for hexadecimal,
58  // a leading "0x" or "0X" for "%#x" and "%#X" respectively,
59  // specification of minimum digits precision, output field
60  // width, space or zero padding, and '-' for left or right
61  // justification.
62  //
63  func (x *Int) Format(s fmt.State, ch rune) {
64  	// determine base
65  	var base int
66  	switch ch {
67  	case 'b':
68  		base = 2
69  	case 'o':
70  		base = 8
71  	case 'd', 's', 'v':
72  		base = 10
73  	case 'x', 'X':
74  		base = 16
75  	default:
76  		// unknown format
77  		fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String())
78  		return
79  	}
80
81  	if x == nil {
82  		fmt.Fprint(s, "<nil>")
83  		return
84  	}
85
86  	// determine sign character
87  	sign := ""
88  	switch {
89  	case x.neg:
90  		sign = "-"
91  	case s.Flag('+'): // supersedes ' ' when both specified
92  		sign = "+"
93  	case s.Flag(' '):
94  		sign = " "
95  	}
96
97  	// determine prefix characters for indicating output base
98  	prefix := ""
99  	if s.Flag('#') {
100  		switch ch {
101  		case 'o': // octal
102  			prefix = "0"
104  			prefix = "0x"
105  		case 'X':
106  			prefix = "0X"
107  		}
108  	}
109
110  	digits := x.abs.utoa(base)
111  	if ch == 'X' {
112  		// faster than bytes.ToUpper
113  		for i, d := range digits {
114  			if 'a' <= d && d <= 'z' {
115  				digits[i] = 'A' + (d - 'a')
116  			}
117  		}
118  	}
119
120  	// number of characters for the three classes of number padding
121  	var left int  // space characters to left of digits for right justification ("%8d")
122  	var zeros int // zero characters (actually cs[0]) as left-most digits ("%.8d")
123  	var right int // space characters to right of digits for left justification ("%-8d")
124
125  	// determine number padding from precision: the least number of digits to output
126  	precision, precisionSet := s.Precision()
127  	if precisionSet {
128  		switch {
129  		case len(digits) < precision:
130  			zeros = precision - len(digits) // count of zero padding
131  		case len(digits) == 1 && digits[0] == '0' && precision == 0:
132  			return // print nothing if zero value (x == 0) and zero precision ("." or ".0")
133  		}
134  	}
135
136  	// determine field pad from width: the least number of characters to output
137  	length := len(sign) + len(prefix) + zeros + len(digits)
138  	if width, widthSet := s.Width(); widthSet && length < width { // pad as specified
139  		switch d := width - length; {
140  		case s.Flag('-'):
141  			// pad on the right with spaces; supersedes '0' when both specified
142  			right = d
143  		case s.Flag('0') && !precisionSet:
144  			// pad with zeros unless precision also specified
145  			zeros = d
146  		default:
147  			// pad on the left with spaces
148  			left = d
149  		}
150  	}
151
153  	writeMultiple(s, " ", left)
154  	writeMultiple(s, sign, 1)
155  	writeMultiple(s, prefix, 1)
156  	writeMultiple(s, "0", zeros)
157  	s.Write(digits)
158  	writeMultiple(s, " ", right)
159  }
160
161  // scan sets z to the integer value corresponding to the longest possible prefix
162  // read from r representing a signed integer number in a given conversion base.
163  // It returns z, the actual conversion base used, and an error, if any. In the
164  // error case, the value of z is undefined but the returned value is nil. The
165  // syntax follows the syntax of integer literals in Go.
166  //
167  // The base argument must be 0 or a value from 2 through MaxBase. If the base
168  // is 0, the string prefix determines the actual conversion base. A prefix of
169  // ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
170  // ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
171  //
172  func (z *Int) scan(r io.ByteScanner, base int) (*Int, int, error) {
173  	// determine sign
174  	neg, err := scanSign(r)
175  	if err != nil {
176  		return nil, 0, err
177  	}
178
179  	// determine mantissa
180  	z.abs, base, _, err = z.abs.scan(r, base, false)
181  	if err != nil {
182  		return nil, base, err
183  	}
184  	z.neg = len(z.abs) > 0 && neg // 0 has no sign
185
186  	return z, base, nil
187  }
188
189  func scanSign(r io.ByteScanner) (neg bool, err error) {
190  	var ch byte
191  	if ch, err = r.ReadByte(); err != nil {
192  		return false, err
193  	}
194  	switch ch {
195  	case '-':
196  		neg = true
197  	case '+':
198  		// nothing to do
199  	default:
201  	}
202  	return
203  }
204
205  // byteReader is a local wrapper around fmt.ScanState;
206  // it implements the ByteReader interface.
208  	fmt.ScanState
209  }
210
212  	ch, size, err := r.ReadRune()
213  	if size != 1 && err == nil {
214  		err = fmt.Errorf("invalid rune %#U", ch)
215  	}
216  	return byte(ch), err
217  }
218
221  }
222
223  var _ fmt.Scanner = intOne // *Int must implement fmt.Scanner
224
225  // Scan is a support routine for fmt.Scanner; it sets z to the value of
226  // the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
228  func (z *Int) Scan(s fmt.ScanState, ch rune) error {
229  	s.SkipSpace() // skip leading space characters
230  	base := 0
231  	switch ch {
232  	case 'b':
233  		base = 2
234  	case 'o':
235  		base = 8
236  	case 'd':
237  		base = 10
238  	case 'x', 'X':
239  		base = 16
240  	case 's', 'v':
241  		// let scan determine the base
242  	default:
243  		return errors.New("Int.Scan: invalid verb")
244  	}
245  	_, _, err := z.scan(byteReader{s}, base)
246  	return err
247  }
248
```

View as plain text