1
2
3
4
5
6
7
8
9
10
11
12 package strconv
13
14 type decimal struct {
15
16
17 d [2000]byte
18 nd int
19 dp int
20 }
21
22 func (a *decimal) String() string {
23 n := 10 + a.nd
24 if a.dp > 0 {
25 n += a.dp
26 }
27 if a.dp < 0 {
28 n += -a.dp
29 }
30
31 buf := make([]byte, n)
32 w := 0
33 switch {
34 case a.nd == 0:
35 return "0"
36
37 case a.dp <= 0:
38
39 buf[w] = '0'
40 w++
41 buf[w] = '.'
42 w++
43 w += digitZero(buf[w : w+-a.dp])
44 w += copy(buf[w:], a.d[0:a.nd])
45
46 case a.dp < a.nd:
47
48 w += copy(buf[w:], a.d[0:a.dp])
49 buf[w] = '.'
50 w++
51 w += copy(buf[w:], a.d[a.dp:a.nd])
52
53 default:
54
55 w += copy(buf[w:], a.d[0:a.nd])
56 w += digitZero(buf[w : w+a.dp-a.nd])
57 }
58 return string(buf[0:w])
59 }
60
61 func digitZero(dst []byte) int {
62 for i := range dst {
63 dst[i] = '0'
64 }
65 return len(dst)
66 }
67
68
69
70
71 func trim(a *decimal) {
72 for a.nd > 0 && a.d[a.nd-1] == '0' {
73 a.nd--
74 }
75 if a.nd == 0 {
76 a.dp = 0
77 }
78 }
79
80
81 func (a *decimal) Assign(v uint64) {
82 var buf [50]byte
83
84
85 n := 0
86 for v > 0 {
87 v1 := v / 10
88 v -= 10 * v1
89 buf[n] = byte(v + '0')
90 n++
91 v = v1
92 }
93
94
95 a.nd = 0
96 for n--; n >= 0; n-- {
97 a.d[a.nd] = buf[n]
98 a.nd++
99 }
100 a.dp = a.nd
101 trim(a)
102 }
103
104 func newDecimal(i uint64) *decimal {
105 a := new(decimal)
106 a.Assign(i)
107 return a
108 }
109
110
111
112 const maxShift = 27
113
114
115 func rightShift(a *decimal, k uint) {
116 r := 0
117 w := 0
118
119
120 n := 0
121 for ; n>>k == 0; r++ {
122 if r >= a.nd {
123 if n == 0 {
124
125 a.nd = 0
126 return
127 }
128 for n>>k == 0 {
129 n = n * 10
130 r++
131 }
132 break
133 }
134 c := int(a.d[r])
135 n = n*10 + c - '0'
136 }
137 a.dp -= r - 1
138
139
140 for ; r < a.nd; r++ {
141 c := int(a.d[r])
142 dig := n >> k
143 n -= dig << k
144 a.d[w] = byte(dig + '0')
145 w++
146 n = n*10 + c - '0'
147 }
148
149
150 for n > 0 {
151 dig := n >> k
152 n -= dig << k
153 a.d[w] = byte(dig + '0')
154 w++
155 n = n * 10
156 }
157
158 a.nd = w
159 trim(a)
160 }
161
162
163
164
165
166
167
168
169
170
171
172 type leftCheat struct {
173 delta int
174 cutoff string
175 }
176
177 var leftcheats = []leftCheat{
178
179
180
181 182 183 184 185 186 187 188 189
190 {0, ""},
191 {1, "5"},
192 {1, "25"},
193 {1, "125"},
194 {2, "625"},
195 {2, "3125"},
196 {2, "15625"},
197 {3, "78125"},
198 {3, "390625"},
199 {3, "1953125"},
200 {4, "9765625"},
201 {4, "48828125"},
202 {4, "244140625"},
203 {4, "1220703125"},
204 {5, "6103515625"},
205 {5, "30517578125"},
206 {5, "152587890625"},
207 {6, "762939453125"},
208 {6, "3814697265625"},
209 {6, "19073486328125"},
210 {7, "95367431640625"},
211 {7, "476837158203125"},
212 {7, "2384185791015625"},
213 {7, "11920928955078125"},
214 {8, "59604644775390625"},
215 {8, "298023223876953125"},
216 {8, "1490116119384765625"},
217 {9, "7450580596923828125"},
218 }
219
220
221 func prefixIsLessThan(b []byte, s string) bool {
222 for i := 0; i < len(s); i++ {
223 if i >= len(b) {
224 return true
225 }
226 if b[i] != s[i] {
227 return b[i] < s[i]
228 }
229 }
230 return false
231 }
232
233
234 func leftShift(a *decimal, k uint) {
235 delta := leftcheats[k].delta
236 if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
237 delta--
238 }
239
240 r := a.nd
241 w := a.nd + delta
242 n := 0
243
244
245 for r--; r >= 0; r-- {
246 n += (int(a.d[r]) - '0') << k
247 quo := n / 10
248 rem := n - 10*quo
249 w--
250 a.d[w] = byte(rem + '0')
251 n = quo
252 }
253
254
255 for n > 0 {
256 quo := n / 10
257 rem := n - 10*quo
258 w--
259 a.d[w] = byte(rem + '0')
260 n = quo
261 }
262
263 a.nd += delta
264 a.dp += delta
265 trim(a)
266 }
267
268
269
270 func (a *decimal) Shift(k int) *decimal {
271 switch {
272 case a.nd == 0:
273
274 case k > 0:
275 for k > maxShift {
276 leftShift(a, maxShift)
277 k -= maxShift
278 }
279 leftShift(a, uint(k))
280 case k < 0:
281 for k < -maxShift {
282 rightShift(a, maxShift)
283 k += maxShift
284 }
285 rightShift(a, uint(-k))
286 }
287 return a
288 }
289
290
291 func shouldRoundUp(a *decimal, nd int) bool {
292 if nd < 0 || nd >= a.nd {
293 return false
294 }
295 if a.d[nd] == '5' && nd+1 == a.nd {
296 return nd > 0 && (a.d[nd-1]-'0')%2 != 0
297 }
298
299 return a.d[nd] >= '5'
300 }
301
302
303
304
305
306
307 func (a *decimal) Round(nd int) *decimal {
308 if nd < 0 || nd >= a.nd {
309 return a
310 }
311 if shouldRoundUp(a, nd) {
312 return a.RoundUp(nd)
313 }
314 return a.RoundDown(nd)
315 }
316
317
318
319 func (a *decimal) RoundDown(nd int) *decimal {
320 if nd < 0 || nd >= a.nd {
321 return a
322 }
323 a.nd = nd
324 trim(a)
325 return a
326 }
327
328
329
330 func (a *decimal) RoundUp(nd int) *decimal {
331 if nd < 0 || nd >= a.nd {
332 return a
333 }
334
335
336 for i := nd - 1; i >= 0; i-- {
337 c := a.d[i]
338 if c < '9' {
339 a.d[i]++
340 a.nd = i + 1
341 return a
342 }
343 }
344
345
346
347 a.d[0] = '1'
348 a.nd = 1
349 a.dp++
350 return a
351 }
352
353
354
355 func (a *decimal) RoundedInteger() uint64 {
356 if a.dp > 20 {
357 return 0xFFFFFFFFFFFFFFFF
358 }
359 var i int
360 n := uint64(0)
361 for i = 0; i < a.dp && i < a.nd; i++ {
362 n = n*10 + uint64(a.d[i]-'0')
363 }
364 for ; i < a.dp; i++ {
365 n *= 10
366 }
367 if shouldRoundUp(a, a.dp) {
368 n++
369 }
370 return n
371 }