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