Source file
src/strconv/atof.go
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
582 if !trunc {
583 if f, ok := atof32exact(mantissa, exp, neg); ok {
584 return f, n, nil
585 }
586 }
587 f, ok := eiselLemire32(mantissa, exp, neg)
588 if ok {
589 if !trunc {
590 return f, n, nil
591 }
592
593
594
595 fUp, ok := eiselLemire32(mantissa+1, exp, neg)
596 if ok && f == fUp {
597 return f, n, nil
598 }
599 }
600 }
601
602
603 var d decimal
604 if !d.set(s[:n]) {
605 return 0, n, syntaxError(fnParseFloat, s)
606 }
607 b, ovf := d.floatBits(&float32info)
608 f = math.Float32frombits(uint32(b))
609 if ovf {
610 err = rangeError(fnParseFloat, s)
611 }
612 return f, n, err
613 }
614
615 func atof64(s string) (f float64, n int, err error) {
616 if val, n, ok := special(s); ok {
617 return val, n, nil
618 }
619
620 mantissa, exp, neg, trunc, hex, n, ok := readFloat(s)
621 if !ok {
622 return 0, n, syntaxError(fnParseFloat, s)
623 }
624
625 if hex {
626 f, err := atofHex(s[:n], &float64info, mantissa, exp, neg, trunc)
627 return f, n, err
628 }
629
630 if optimize {
631
632
633 if !trunc {
634 if f, ok := atof64exact(mantissa, exp, neg); ok {
635 return f, n, nil
636 }
637 }
638 f, ok := eiselLemire64(mantissa, exp, neg)
639 if ok {
640 if !trunc {
641 return f, n, nil
642 }
643
644
645
646 fUp, ok := eiselLemire64(mantissa+1, exp, neg)
647 if ok && f == fUp {
648 return f, n, nil
649 }
650 }
651 }
652
653
654 var d decimal
655 if !d.set(s[:n]) {
656 return 0, n, syntaxError(fnParseFloat, s)
657 }
658 b, ovf := d.floatBits(&float64info)
659 f = math.Float64frombits(b)
660 if ovf {
661 err = rangeError(fnParseFloat, s)
662 }
663 return f, n, err
664 }
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690 func ParseFloat(s string, bitSize int) (float64, error) {
691 f, n, err := parseFloatPrefix(s, bitSize)
692 if n != len(s) && (err == nil || err.(*NumError).Err != ErrSyntax) {
693 return 0, syntaxError(fnParseFloat, s)
694 }
695 return f, err
696 }
697
698 func parseFloatPrefix(s string, bitSize int) (float64, int, error) {
699 if bitSize == 32 {
700 f, n, err := atof32(s)
701 return float64(f), n, err
702 }
703 return atof64(s)
704 }
705
View as plain text