Source file
src/strconv/atof.go
Documentation: strconv
1
2
3
4
5 package strconv
6
7
8
9
10
11
12
13 import "math"
14
15 var optimize = true
16
17
18
19
20 func commonPrefixLenIgnoreCase(s, prefix string) int {
21 n := len(prefix)
22 if n > len(s) {
23 n = len(s)
24 }
25 for i := 0; i < n; i++ {
26 c := s[i]
27 if 'A' <= c && c <= 'Z' {
28 c += 'a' - 'A'
29 }
30 if c != prefix[i] {
31 return i
32 }
33 }
34 return n
35 }
36
37
38
39
40
41
42 func special(s string) (f float64, n int, ok bool) {
43 if len(s) == 0 {
44 return 0, 0, false
45 }
46 sign := 1
47 nsign := 0
48 switch s[0] {
49 case '+', '-':
50 if s[0] == '-' {
51 sign = -1
52 }
53 nsign = 1
54 s = s[1:]
55 fallthrough
56 case 'i', 'I':
57 n := commonPrefixLenIgnoreCase(s, "infinity")
58
59
60 if 3 < n && n < 8 {
61 n = 3
62 }
63 if n == 3 || n == 8 {
64 return math.Inf(sign), nsign + n, true
65 }
66 case 'n', 'N':
67 if commonPrefixLenIgnoreCase(s, "nan") == 3 {
68 return math.NaN(), 3, true
69 }
70 }
71 return 0, 0, false
72 }
73
74 func (b *decimal) set(s string) (ok bool) {
75 i := 0
76 b.neg = false
77 b.trunc = false
78
79
80 if i >= len(s) {
81 return
82 }
83 switch {
84 case s[i] == '+':
85 i++
86 case s[i] == '-':
87 b.neg = true
88 i++
89 }
90
91
92 sawdot := false
93 sawdigits := false
94 for ; i < len(s); i++ {
95 switch {
96 case s[i] == '_':
97
98 continue
99 case s[i] == '.':
100 if sawdot {
101 return
102 }
103 sawdot = true
104 b.dp = b.nd
105 continue
106
107 case '0' <= s[i] && s[i] <= '9':
108 sawdigits = true
109 if s[i] == '0' && b.nd == 0 {
110 b.dp--
111 continue
112 }
113 if b.nd < len(b.d) {
114 b.d[b.nd] = s[i]
115 b.nd++
116 } else if s[i] != '0' {
117 b.trunc = true
118 }
119 continue
120 }
121 break
122 }
123 if !sawdigits {
124 return
125 }
126 if !sawdot {
127 b.dp = b.nd
128 }
129
130
131
132
133
134
135 if i < len(s) && lower(s[i]) == 'e' {
136 i++
137 if i >= len(s) {
138 return
139 }
140 esign := 1
141 if s[i] == '+' {
142 i++
143 } else if s[i] == '-' {
144 i++
145 esign = -1
146 }
147 if i >= len(s) || s[i] < '0' || s[i] > '9' {
148 return
149 }
150 e := 0
151 for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
152 if s[i] == '_' {
153
154 continue
155 }
156 if e < 10000 {
157 e = e*10 + int(s[i]) - '0'
158 }
159 }
160 b.dp += e * esign
161 }
162
163 if i != len(s) {
164 return
165 }
166
167 ok = true
168 return
169 }
170
171
172
173
174
175 func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex bool, i int, ok bool) {
176 underscores := false
177
178
179 if i >= len(s) {
180 return
181 }
182 switch {
183 case s[i] == '+':
184 i++
185 case s[i] == '-':
186 neg = true
187 i++
188 }
189
190
191 base := uint64(10)
192 maxMantDigits := 19
193 expChar := byte('e')
194 if i+2 < len(s) && s[i] == '0' && lower(s[i+1]) == 'x' {
195 base = 16
196 maxMantDigits = 16
197 i += 2
198 expChar = 'p'
199 hex = true
200 }
201 sawdot := false
202 sawdigits := false
203 nd := 0
204 ndMant := 0
205 dp := 0
206 loop:
207 for ; i < len(s); i++ {
208 switch c := s[i]; true {
209 case c == '_':
210 underscores = true
211 continue
212
213 case c == '.':
214 if sawdot {
215 break loop
216 }
217 sawdot = true
218 dp = nd
219 continue
220
221 case '0' <= c && c <= '9':
222 sawdigits = true
223 if c == '0' && nd == 0 {
224 dp--
225 continue
226 }
227 nd++
228 if ndMant < maxMantDigits {
229 mantissa *= base
230 mantissa += uint64(c - '0')
231 ndMant++
232 } else if c != '0' {
233 trunc = true
234 }
235 continue
236
237 case base == 16 && 'a' <= lower(c) && lower(c) <= 'f':
238 sawdigits = true
239 nd++
240 if ndMant < maxMantDigits {
241 mantissa *= 16
242 mantissa += uint64(lower(c) - 'a' + 10)
243 ndMant++
244 } else {
245 trunc = true
246 }
247 continue
248 }
249 break
250 }
251 if !sawdigits {
252 return
253 }
254 if !sawdot {
255 dp = nd
256 }
257
258 if base == 16 {
259 dp *= 4
260 ndMant *= 4
261 }
262
263
264
265
266
267
268 if i < len(s) && lower(s[i]) == expChar {
269 i++
270 if i >= len(s) {
271 return
272 }
273 esign := 1
274 if s[i] == '+' {
275 i++
276 } else if s[i] == '-' {
277 i++
278 esign = -1
279 }
280 if i >= len(s) || s[i] < '0' || s[i] > '9' {
281 return
282 }
283 e := 0
284 for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
285 if s[i] == '_' {
286 underscores = true
287 continue
288 }
289 if e < 10000 {
290 e = e*10 + int(s[i]) - '0'
291 }
292 }
293 dp += e * esign
294 } else if base == 16 {
295
296 return
297 }
298
299 if mantissa != 0 {
300 exp = dp - ndMant
301 }
302
303 if underscores && !underscoreOK(s[:i]) {
304 return
305 }
306
307 ok = true
308 return
309 }
310
311
312 var powtab = []int{1, 3, 6, 9, 13, 16, 19, 23, 26}
313
314 func (d *decimal) floatBits(flt *floatInfo) (b uint64, overflow bool) {
315 var exp int
316 var mant uint64
317
318
319 if d.nd == 0 {
320 mant = 0
321 exp = flt.bias
322 goto out
323 }
324
325
326
327
328 if d.dp > 310 {
329 goto overflow
330 }
331 if d.dp < -330 {
332
333 mant = 0
334 exp = flt.bias
335 goto out
336 }
337
338
339 exp = 0
340 for d.dp > 0 {
341 var n int
342 if d.dp >= len(powtab) {
343 n = 27
344 } else {
345 n = powtab[d.dp]
346 }
347 d.Shift(-n)
348 exp += n
349 }
350 for d.dp < 0 || d.dp == 0 && d.d[0] < '5' {
351 var n int
352 if -d.dp >= len(powtab) {
353 n = 27
354 } else {
355 n = powtab[-d.dp]
356 }
357 d.Shift(n)
358 exp -= n
359 }
360
361
362 exp--
363
364
365
366
367 if exp < flt.bias+1 {
368 n := flt.bias + 1 - exp
369 d.Shift(-n)
370 exp += n
371 }
372
373 if exp-flt.bias >= 1<<flt.expbits-1 {
374 goto overflow
375 }
376
377
378 d.Shift(int(1 + flt.mantbits))
379 mant = d.RoundedInteger()
380
381
382 if mant == 2<<flt.mantbits {
383 mant >>= 1
384 exp++
385 if exp-flt.bias >= 1<<flt.expbits-1 {
386 goto overflow
387 }
388 }
389
390
391 if mant&(1<<flt.mantbits) == 0 {
392 exp = flt.bias
393 }
394 goto out
395
396 overflow:
397
398 mant = 0
399 exp = 1<<flt.expbits - 1 + flt.bias
400 overflow = true
401
402 out:
403
404 bits := mant & (uint64(1)<<flt.mantbits - 1)
405 bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
406 if d.neg {
407 bits |= 1 << flt.mantbits << flt.expbits
408 }
409 return bits, overflow
410 }
411
412
413 var float64pow10 = []float64{
414 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
415 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
416 1e20, 1e21, 1e22,
417 }
418 var float32pow10 = []float32{1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10}
419
420
421
422
423
424
425
426
427 func atof64exact(mantissa uint64, exp int, neg bool) (f float64, ok bool) {
428 if mantissa>>float64info.mantbits != 0 {
429 return
430 }
431 f = float64(mantissa)
432 if neg {
433 f = -f
434 }
435 switch {
436 case exp == 0:
437
438 return f, true
439
440
441 case exp > 0 && exp <= 15+22:
442
443
444 if exp > 22 {
445 f *= float64pow10[exp-22]
446 exp = 22
447 }
448 if f > 1e15 || f < -1e15 {
449
450 return
451 }
452 return f * float64pow10[exp], true
453 case exp < 0 && exp >= -22:
454 return f / float64pow10[-exp], true
455 }
456 return
457 }
458
459
460
461 func atof32exact(mantissa uint64, exp int, neg bool) (f float32, ok bool) {
462 if mantissa>>float32info.mantbits != 0 {
463 return
464 }
465 f = float32(mantissa)
466 if neg {
467 f = -f
468 }
469 switch {
470 case exp == 0:
471 return f, true
472
473
474 case exp > 0 && exp <= 7+10:
475
476
477 if exp > 10 {
478 f *= float32pow10[exp-10]
479 exp = 10
480 }
481 if f > 1e7 || f < -1e7 {
482
483 return
484 }
485 return f * float32pow10[exp], true
486 case exp < 0 && exp >= -10:
487 return f / float32pow10[-exp], true
488 }
489 return
490 }
491
492
493
494
495
496
497 func atofHex(s string, flt *floatInfo, mantissa uint64, exp int, neg, trunc bool) (float64, error) {
498 maxExp := 1<<flt.expbits + flt.bias - 2
499 minExp := flt.bias + 1
500 exp += int(flt.mantbits)
501
502
503
504
505
506
507
508 for mantissa != 0 && mantissa>>(flt.mantbits+2) == 0 {
509 mantissa <<= 1
510 exp--
511 }
512 if trunc {
513 mantissa |= 1
514 }
515 for mantissa>>(1+flt.mantbits+2) != 0 {
516 mantissa = mantissa>>1 | mantissa&1
517 exp++
518 }
519
520
521
522
523 for mantissa > 1 && exp < minExp-2 {
524 mantissa = mantissa>>1 | mantissa&1
525 exp++
526 }
527
528
529 round := mantissa & 3
530 mantissa >>= 2
531 round |= mantissa & 1
532 exp += 2
533 if round == 3 {
534 mantissa++
535 if mantissa == 1<<(1+flt.mantbits) {
536 mantissa >>= 1
537 exp++
538 }
539 }
540
541 if mantissa>>flt.mantbits == 0 {
542 exp = flt.bias
543 }
544 var err error
545 if exp > maxExp {
546 mantissa = 1 << flt.mantbits
547 exp = maxExp + 1
548 err = rangeError(fnParseFloat, s)
549 }
550
551 bits := mantissa & (1<<flt.mantbits - 1)
552 bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
553 if neg {
554 bits |= 1 << flt.mantbits << flt.expbits
555 }
556 if flt == &float32info {
557 return float64(math.Float32frombits(uint32(bits))), err
558 }
559 return math.Float64frombits(bits), err
560 }
561
562 const fnParseFloat = "ParseFloat"
563
564 func atof32(s string) (f float32, n int, err error) {
565 if val, n, ok := special(s); ok {
566 return float32(val), n, nil
567 }
568
569 mantissa, exp, neg, trunc, hex, n, ok := readFloat(s)
570 if !ok {
571 return 0, n, syntaxError(fnParseFloat, s)
572 }
573
574 if hex {
575 f, err := atofHex(s[:n], &float32info, mantissa, exp, neg, trunc)
576 return float32(f), n, err
577 }
578
579 if optimize {
580
581 if !trunc {
582 if f, ok := atof32exact(mantissa, exp, neg); ok {
583 return f, n, nil
584 }
585 }
586
587 ext := new(extFloat)
588 if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float32info); ok {
589 b, ovf := ext.floatBits(&float32info)
590 f = math.Float32frombits(uint32(b))
591 if ovf {
592 err = rangeError(fnParseFloat, s)
593 }
594 return f, n, err
595 }
596 }
597
598
599 var d decimal
600 if !d.set(s[:n]) {
601 return 0, n, syntaxError(fnParseFloat, s)
602 }
603 b, ovf := d.floatBits(&float32info)
604 f = math.Float32frombits(uint32(b))
605 if ovf {
606 err = rangeError(fnParseFloat, s)
607 }
608 return f, n, err
609 }
610
611 func atof64(s string) (f float64, n int, err error) {
612 if val, n, ok := special(s); ok {
613 return val, n, nil
614 }
615
616 mantissa, exp, neg, trunc, hex, n, ok := readFloat(s)
617 if !ok {
618 return 0, n, syntaxError(fnParseFloat, s)
619 }
620
621 if hex {
622 f, err := atofHex(s[:n], &float64info, mantissa, exp, neg, trunc)
623 return f, n, err
624 }
625
626 if optimize {
627
628 if !trunc {
629 if f, ok := atof64exact(mantissa, exp, neg); ok {
630 return f, n, nil
631 }
632 }
633
634 ext := new(extFloat)
635 if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float64info); ok {
636 b, ovf := ext.floatBits(&float64info)
637 f = math.Float64frombits(b)
638 if ovf {
639 err = rangeError(fnParseFloat, s)
640 }
641 return f, n, err
642 }
643 }
644
645
646 var d decimal
647 if !d.set(s[:n]) {
648 return 0, n, syntaxError(fnParseFloat, s)
649 }
650 b, ovf := d.floatBits(&float64info)
651 f = math.Float64frombits(b)
652 if ovf {
653 err = rangeError(fnParseFloat, s)
654 }
655 return f, n, err
656 }
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682 func ParseFloat(s string, bitSize int) (float64, error) {
683 f, n, err := parseFloatPrefix(s, bitSize)
684 if err == nil && n != len(s) {
685 return 0, syntaxError(fnParseFloat, s)
686 }
687 return f, err
688 }
689
690 func parseFloatPrefix(s string, bitSize int) (float64, int, error) {
691 if bitSize == 32 {
692 f, n, err := atof32(s)
693 return float64(f), n, err
694 }
695 return atof64(s)
696 }
697
View as plain text