1
2
3
4
5 package strconv
6
7 import "math/bits"
8
9
10
11
12 func FormatUint(i uint64, base int) string {
13 if base == 10 {
14 if i < nSmalls {
15 return small(int(i))
16 }
17 var a [24]byte
18 j := formatBase10(a[:], i)
19 return string(a[j:])
20 }
21 _, s := formatBits(nil, i, base, false, false)
22 return s
23 }
24
25
26
27
28 func FormatInt(i int64, base int) string {
29 if base == 10 {
30 if 0 <= i && i < nSmalls {
31 return small(int(i))
32 }
33 var a [24]byte
34 u := uint64(i)
35 if i < 0 {
36 u = -u
37 }
38 j := formatBase10(a[:], u)
39 if i < 0 {
40 j--
41 a[j] = '-'
42 }
43 return string(a[j:])
44 }
45 _, s := formatBits(nil, uint64(i), base, i < 0, false)
46 return s
47 }
48
49
50 func Itoa(i int) string {
51 return FormatInt(int64(i), 10)
52 }
53
54
55
56 func AppendInt(dst []byte, i int64, base int) []byte {
57 u := uint64(i)
58 if i < 0 {
59 dst = append(dst, '-')
60 u = -u
61 }
62 return AppendUint(dst, u, base)
63 }
64
65
66
67 func AppendUint(dst []byte, i uint64, base int) []byte {
68 if base == 10 {
69 if i < nSmalls {
70 return append(dst, small(int(i))...)
71 }
72 var a [24]byte
73 j := formatBase10(a[:], i)
74 return append(dst, a[j:]...)
75 }
76 dst, _ = formatBits(dst, i, base, false, true)
77 return dst
78 }
79
80 const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
81
82
83
84
85
86
87
88 func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s string) {
89 if base < 2 || base == 10 || base > len(digits) {
90 panic("strconv: illegal AppendInt/FormatInt base")
91 }
92
93
94 var a [64 + 1]byte
95 i := len(a)
96 if neg {
97 u = -u
98 }
99
100
101
102
103 if isPowerOfTwo(base) {
104
105 shift := uint(bits.TrailingZeros(uint(base)))
106 b := uint64(base)
107 m := uint(base) - 1
108 for u >= b {
109 i--
110 a[i] = digits[uint(u)&m]
111 u >>= shift
112 }
113
114 i--
115 a[i] = digits[uint(u)]
116 } else {
117
118 b := uint64(base)
119 for u >= b {
120 i--
121
122
123
124 q := u / b
125 a[i] = digits[uint(u-q*b)]
126 u = q
127 }
128
129 i--
130 a[i] = digits[uint(u)]
131 }
132
133
134 if neg {
135 i--
136 a[i] = '-'
137 }
138
139 if append_ {
140 d = append(dst, a[i:]...)
141 return
142 }
143 s = string(a[i:])
144 return
145 }
146
147 func isPowerOfTwo(x int) bool {
148 return x&(x-1) == 0
149 }
150
151 const nSmalls = 100
152
153
154
155
156 const smalls = "00010203040506070809" +
157 "10111213141516171819" +
158 "20212223242526272829" +
159 "30313233343536373839" +
160 "40414243444546474849" +
161 "50515253545556575859" +
162 "60616263646566676869" +
163 "70717273747576777879" +
164 "80818283848586878889" +
165 "90919293949596979899"
166
167 const host64bit = ^uint(0)>>32 != 0
168
169
170 func small(i int) string {
171 if i < 10 {
172 return digits[i : i+1]
173 }
174 return smalls[i*2 : i*2+2]
175 }
176
177
178
179
180
181 func RuntimeFormatBase10(a []byte, u uint64) int {
182 return formatBase10(a, u)
183 }
184
185
186
187
188
189
190
191 func formatBase10(a []byte, u uint64) int {
192
193
194
195
196
197 i := len(a)
198 for (host64bit && u>>29 != 0) || (!host64bit && uint32(u)>>29|uint32(u>>32) != 0) {
199 var lo uint32
200 u, lo = u/1e9, uint32(u%1e9)
201
202
203 for range 4 {
204 var dd uint32
205 lo, dd = lo/100, (lo%100)*2
206 i -= 2
207 a[i+0], a[i+1] = smalls[dd+0], smalls[dd+1]
208 }
209 i--
210 a[i] = smalls[lo*2+1]
211
212
213
214
215
216 if u == 0 {
217 return i
218 }
219 }
220
221
222 lo := uint32(u)
223 for lo >= 100 {
224 var dd uint32
225 lo, dd = lo/100, (lo%100)*2
226 i -= 2
227 a[i+0], a[i+1] = smalls[dd+0], smalls[dd+1]
228 }
229 i--
230 dd := lo * 2
231 a[i] = smalls[dd+1]
232 if lo >= 10 {
233 i--
234 a[i] = smalls[dd+0]
235 }
236 return i
237 }
238
View as plain text