float.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
  2. // Use of this source code is governed by a MIT license found in the LICENSE file.
  3. package codec
  4. import (
  5. "strconv"
  6. )
  7. // func parseFloat(b []byte, bitsize int) (f float64, err error) {
  8. // if bitsize == 32 {
  9. // return parseFloat32(b)
  10. // } else {
  11. // return parseFloat64(b)
  12. // }
  13. // }
  14. func parseFloat32(b []byte) (f float32, err error) {
  15. return parseFloat32_custom(b)
  16. // return parseFloat32_strconv(b)
  17. }
  18. func parseFloat64(b []byte) (f float64, err error) {
  19. return parseFloat64_custom(b)
  20. // return parseFloat64_strconv(b)
  21. }
  22. func parseFloat32_strconv(b []byte) (f float32, err error) {
  23. f64, err := strconv.ParseFloat(stringView(b), 32)
  24. f = float32(f64)
  25. return
  26. }
  27. func parseFloat64_strconv(b []byte) (f float64, err error) {
  28. return strconv.ParseFloat(stringView(b), 64)
  29. }
  30. // ------ parseFloat custom below --------
  31. // We assume that a lot of floating point numbers in json files will be
  32. // those that are handwritten, and with defined precision (in terms of number
  33. // of digits after decimal point), etc.
  34. //
  35. // We further assume that this ones can be written in exact format.
  36. //
  37. // strconv.ParseFloat has some unnecessary overhead which we can do without
  38. // for the common case:
  39. //
  40. // - expensive char-by-char check to see if underscores are in right place
  41. // - testing for and skipping underscores
  42. // - check if the string matches ignorecase +/- inf, +/- infinity, nan
  43. // - support for base 16 (0xFFFF...)
  44. //
  45. // The functions below will try a fast-path for floats which can be decoded
  46. // without any loss of precision, meaning they:
  47. //
  48. // - fits within the significand bits of the 32-bits or 64-bits
  49. // - exponent fits within the exponent value
  50. // - there is no truncation (any extra numbers are all trailing zeros)
  51. //
  52. // To figure out what the values are for maxMantDigits, use this idea below:
  53. //
  54. // 2^23 = 838 8608 (between 10^ 6 and 10^ 7) (significand bits of uint32)
  55. // 2^32 = 42 9496 7296 (between 10^ 9 and 10^10) (full uint32)
  56. // 2^52 = 4503 5996 2737 0496 (between 10^15 and 10^16) (significand bits of uint64)
  57. // 2^64 = 1844 6744 0737 0955 1616 (between 10^19 and 10^20) (full uint64)
  58. //
  59. // Note: we only allow for up to what can comfortably fit into the significand
  60. // ignoring the exponent, and we only try to parse iff significand fits.
  61. const (
  62. thousand = 1000
  63. million = thousand * thousand
  64. billion = thousand * million
  65. trillion = thousand * billion
  66. quadrillion = thousand * trillion
  67. quintillion = thousand * quadrillion
  68. )
  69. // Exact powers of 10.
  70. var uint64pow10 = [...]uint64{
  71. 1, 10, 100,
  72. 1 * thousand, 10 * thousand, 100 * thousand,
  73. 1 * million, 10 * million, 100 * million,
  74. 1 * billion, 10 * billion, 100 * billion,
  75. 1 * trillion, 10 * trillion, 100 * trillion,
  76. 1 * quadrillion, 10 * quadrillion, 100 * quadrillion,
  77. 1 * quintillion, 10 * quintillion,
  78. }
  79. var float64pow10 = [...]float64{
  80. 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
  81. 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
  82. 1e20, 1e21, 1e22,
  83. }
  84. var float32pow10 = [...]float32{
  85. 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
  86. }
  87. type floatinfo struct {
  88. mantbits uint8
  89. // expbits uint8 // (unused)
  90. // bias int16 // (unused)
  91. is32bit bool
  92. exactPow10 int8 // Exact powers of ten are <= 10^N (32: 10, 64: 22)
  93. exactInts int8 // Exact integers are <= 10^N (for non-float, set to 0)
  94. // maxMantDigits int8 // 10^19 fits in uint64, while 10^9 fits in uint32
  95. mantCutoffIsUint64Cutoff bool
  96. mantCutoff uint64
  97. }
  98. // var fi32 = floatinfo{23, 8, -127, 10, 7, 9, fUint32Cutoff}
  99. // var fi64 = floatinfo{52, 11, -1023, 22, 15, 19, fUint64Cutoff}
  100. // var fi64u = floatinfo{64, 0, -1023, 19, 0, 19, fUint64Cutoff}
  101. // var fi64i = floatinfo{63, 0, -1023, 19, 0, 19, fUint64Cutoff}
  102. var fi32 = floatinfo{23, true, 10, 7, false, 1<<23 - 1}
  103. var fi64 = floatinfo{52, false, 22, 15, false, 1<<52 - 1}
  104. var fi64u = floatinfo{0, false, 19, 0, true, fUint64Cutoff}
  105. var fi64i = floatinfo{0, false, 19, 0, true, fUint64Cutoff}
  106. const fMaxMultiplierForExactPow10_64 = 1e15
  107. const fMaxMultiplierForExactPow10_32 = 1e7
  108. const fUint64Cutoff = (1<<64-1)/10 + 1
  109. const fUint32Cutoff = (1<<32-1)/10 + 1
  110. const fBase = 10
  111. func strconvParseErr(b []byte, fn string) error {
  112. return &strconv.NumError{
  113. Func: fn,
  114. Err: strconv.ErrSyntax,
  115. Num: string(b),
  116. }
  117. }
  118. func parseFloat32_reader(r readFloatResult) (f float32, fail bool) {
  119. // parseFloatDebug(b, 32, false, exp, trunc, ok)
  120. f = float32(r.mantissa)
  121. if r.exp == 0 {
  122. } else if r.exp < 0 { // int / 10^k
  123. f /= float32pow10[uint8(-r.exp)]
  124. } else { // exp > 0
  125. if r.exp > fi32.exactPow10 {
  126. f *= float32pow10[r.exp-fi32.exactPow10]
  127. if f > fMaxMultiplierForExactPow10_32 { // exponent too large - outside range
  128. fail = true
  129. return // ok = false
  130. }
  131. f *= float32pow10[fi32.exactPow10]
  132. } else {
  133. f *= float32pow10[uint8(r.exp)]
  134. }
  135. }
  136. if r.neg {
  137. f = -f
  138. }
  139. return
  140. }
  141. func parseFloat32_custom(b []byte) (f float32, err error) {
  142. r := readFloat(b, fi32)
  143. if r.bad {
  144. return 0, strconvParseErr(b, "ParseFloat")
  145. }
  146. if r.ok {
  147. f, r.bad = parseFloat32_reader(r)
  148. if r.bad {
  149. goto FALLBACK
  150. }
  151. return
  152. }
  153. FALLBACK:
  154. return parseFloat32_strconv(b)
  155. }
  156. func parseFloat64_reader(r readFloatResult) (f float64, fail bool) {
  157. f = float64(r.mantissa)
  158. if r.exp == 0 {
  159. } else if r.exp < 0 { // int / 10^k
  160. f /= float64pow10[-uint8(r.exp)]
  161. } else { // exp > 0
  162. if r.exp > fi64.exactPow10 {
  163. f *= float64pow10[r.exp-fi64.exactPow10]
  164. if f > fMaxMultiplierForExactPow10_64 { // exponent too large - outside range
  165. fail = true
  166. return
  167. }
  168. f *= float64pow10[fi64.exactPow10]
  169. } else {
  170. f *= float64pow10[uint8(r.exp)]
  171. }
  172. }
  173. if r.neg {
  174. f = -f
  175. }
  176. return
  177. }
  178. func parseFloat64_custom(b []byte) (f float64, err error) {
  179. r := readFloat(b, fi64)
  180. if r.bad {
  181. return 0, strconvParseErr(b, "ParseFloat")
  182. }
  183. if r.ok {
  184. f, r.bad = parseFloat64_reader(r)
  185. if r.bad {
  186. goto FALLBACK
  187. }
  188. return
  189. }
  190. FALLBACK:
  191. return parseFloat64_strconv(b)
  192. }
  193. func parseUint64_simple(b []byte) (n uint64, ok bool) {
  194. var i int
  195. var n1 uint64
  196. var c uint8
  197. LOOP:
  198. if i < len(b) {
  199. c = b[i]
  200. // unsigned integers don't overflow well on multiplication, so check cutoff here
  201. // e.g. (maxUint64-5)*10 doesn't overflow well ...
  202. // if n >= fUint64Cutoff || !isDigitChar(b[i]) { // if c < '0' || c > '9' {
  203. if n >= fUint64Cutoff || c < '0' || c > '9' {
  204. return
  205. } else if c == '0' {
  206. n *= fBase
  207. } else {
  208. n1 = n
  209. n = n*fBase + uint64(c-'0')
  210. if n < n1 {
  211. return
  212. }
  213. }
  214. i++
  215. goto LOOP
  216. }
  217. ok = true
  218. return
  219. }
  220. // func parseUint64_simple(b []byte) (n uint64, ok bool) {
  221. // var i int
  222. // var n1 uint64
  223. // LOOP:
  224. // if i < len(b) {
  225. // // unsigned integers don't overflow well on multiplication, so check cutoff here
  226. // // e.g. (maxUint64-5)*10 doesn't overflow well ...
  227. // if n >= fUint64Cutoff || !isDigitChar(b[i]) { // if c < '0' || c > '9' {
  228. // return
  229. // }
  230. // n *= fBase
  231. // n1 = n + uint64(b[i]-'0')
  232. // if n1 < n {
  233. // return
  234. // }
  235. // n = n1
  236. // i++
  237. // goto LOOP
  238. // }
  239. // ok = true
  240. // return
  241. // }
  242. // func parseUint64_simple(b []byte) (n uint64, ok bool) {
  243. // var i int
  244. // var n1 uint64
  245. // LOOP:
  246. // if i < len(b) {
  247. // // unsigned integers don't overflow well on multiplication, so check cutoff here
  248. // // e.g. (maxUint64-5)*10 doesn't overflow well ...
  249. // if n >= fUint64Cutoff { // if c < '0' || c > '9' {
  250. // return
  251. // }
  252. // n *= fBase
  253. // switch b[i] {
  254. // case '0':
  255. // case '1', '2', '3', '4', '5', '6', '7', '8', '9':
  256. // n1 = n
  257. // n += uint64(b[i] - '0')
  258. // if n < n1 {
  259. // return
  260. // }
  261. // default:
  262. // return
  263. // }
  264. // i++
  265. // goto LOOP
  266. // }
  267. // ok = true
  268. // return
  269. // }
  270. // func parseUint64_simple(b []byte) (n uint64, ok bool) {
  271. // var i int
  272. // var n1 uint64
  273. // LOOP:
  274. // if i < len(b) {
  275. // // unsigned integers don't overflow well on multiplication, so check cutoff here
  276. // // e.g. (maxUint64-5)*10 doesn't overflow well ...
  277. // if n >= fUint64Cutoff { // if c < '0' || c > '9' {
  278. // return
  279. // }
  280. // switch b[i] {
  281. // case '0':
  282. // // n = n<<3 + n<<1
  283. // n *= 10
  284. // case '1', '2', '3', '4', '5', '6', '7', '8', '9':
  285. // n1 = n
  286. // // n = n<<3 + n<<1 + uint64(b[i]-'0')
  287. // n = (n * 10) + uint64(b[i]-'0')
  288. // if n < n1 {
  289. // return
  290. // }
  291. // default:
  292. // return
  293. // }
  294. // i++
  295. // goto LOOP
  296. // }
  297. // ok = true
  298. // return
  299. // }
  300. func parseUint64_reader(r readFloatResult) (f uint64, fail bool) {
  301. f = r.mantissa
  302. if r.exp == 0 {
  303. } else if r.exp < 0 { // int / 10^k
  304. if f%uint64pow10[uint8(-r.exp)] != 0 {
  305. fail = true
  306. } else {
  307. f /= uint64pow10[uint8(-r.exp)]
  308. }
  309. } else { // exp > 0
  310. f *= uint64pow10[uint8(r.exp)]
  311. }
  312. return
  313. }
  314. func parseInt64_reader(r readFloatResult) (v int64, fail bool) {
  315. // xdebugf("parseint64_reader: r: %#v", r)
  316. if r.exp == 0 {
  317. } else if r.exp < 0 { // int / 10^k
  318. if r.mantissa%uint64pow10[uint8(-r.exp)] != 0 {
  319. // fail = true
  320. return 0, true
  321. }
  322. r.mantissa /= uint64pow10[uint8(-r.exp)]
  323. } else { // exp > 0
  324. r.mantissa *= uint64pow10[uint8(r.exp)]
  325. }
  326. if chkOvf.Uint2Int(r.mantissa, r.neg) {
  327. fail = true
  328. } else if r.neg {
  329. v = -int64(r.mantissa)
  330. } else {
  331. v = int64(r.mantissa)
  332. }
  333. return
  334. }
  335. // parseNumber will return an integer if only composed of [-]?[0-9]+
  336. // Else it will return a float.
  337. func parseNumber(b []byte, z *fauxUnion, preferSignedInt bool) (err error) {
  338. var ok, neg bool
  339. var f uint64
  340. // var b1 []byte
  341. // if b[0] == '-' {
  342. // neg = true
  343. // b1 = b[1:]
  344. // } else {
  345. // b1 = b
  346. // }
  347. // f, ok = parseUint64_simple(b1)
  348. if len(b) == 0 {
  349. return
  350. }
  351. if b[0] == '-' {
  352. neg = true
  353. f, ok = parseUint64_simple(b[1:])
  354. } else {
  355. f, ok = parseUint64_simple(b)
  356. }
  357. if ok {
  358. if neg {
  359. z.v = valueTypeInt
  360. if chkOvf.Uint2Int(f, neg) {
  361. return strconvParseErr(b, "ParseInt")
  362. }
  363. z.i = -int64(f)
  364. } else if preferSignedInt {
  365. z.v = valueTypeInt
  366. if chkOvf.Uint2Int(f, neg) {
  367. return strconvParseErr(b, "ParseInt")
  368. }
  369. z.i = int64(f)
  370. } else {
  371. z.v = valueTypeUint
  372. z.u = f
  373. }
  374. return
  375. }
  376. z.v = valueTypeFloat
  377. z.f, err = parseFloat64_custom(b)
  378. return
  379. }
  380. type readFloatResult struct {
  381. mantissa uint64
  382. exp int8
  383. neg, sawdot, sawexp, trunc, bad bool
  384. ok bool
  385. _ byte // padding
  386. }
  387. func readFloat(s []byte, y floatinfo) (r readFloatResult) {
  388. // defer func() { xdebugf("readFloat: %#v", r) }()
  389. var i uint // uint, so that we eliminate bounds checking
  390. var slen = uint(len(s))
  391. if slen == 0 {
  392. // read an empty string as the zero value
  393. // r.bad = true
  394. r.ok = true
  395. return
  396. }
  397. if s[0] == '-' {
  398. r.neg = true
  399. i++
  400. }
  401. // we considered punting early if string has length > maxMantDigits, but this doesn't account
  402. // for trailing 0's e.g. 700000000000000000000 can be encoded exactly as it is 7e20
  403. var nd, ndMant, dp int8
  404. var xu uint64
  405. LOOP:
  406. for ; i < slen; i++ {
  407. switch s[i] {
  408. case '.':
  409. if r.sawdot {
  410. r.bad = true
  411. return
  412. }
  413. r.sawdot = true
  414. dp = nd
  415. case 'e', 'E':
  416. r.sawexp = true
  417. break LOOP
  418. case '0':
  419. if nd == 0 {
  420. dp--
  421. continue LOOP
  422. }
  423. nd++
  424. if r.mantissa < y.mantCutoff {
  425. r.mantissa *= fBase
  426. ndMant++
  427. }
  428. case '1', '2', '3', '4', '5', '6', '7', '8', '9':
  429. nd++
  430. if y.mantCutoffIsUint64Cutoff && r.mantissa < fUint64Cutoff {
  431. r.mantissa *= fBase
  432. xu = r.mantissa + uint64(s[i]-'0')
  433. if xu < r.mantissa {
  434. r.trunc = true
  435. return
  436. }
  437. r.mantissa = xu
  438. } else if r.mantissa < y.mantCutoff {
  439. // mantissa = (mantissa << 1) + (mantissa << 3) + uint64(c-'0')
  440. r.mantissa = r.mantissa*fBase + uint64(s[i]-'0')
  441. } else {
  442. r.trunc = true
  443. return
  444. }
  445. ndMant++
  446. default:
  447. r.bad = true
  448. return
  449. }
  450. }
  451. if !r.sawdot {
  452. dp = nd
  453. }
  454. if r.sawexp {
  455. i++
  456. if i < slen {
  457. var eneg bool
  458. if s[i] == '+' {
  459. i++
  460. } else if s[i] == '-' {
  461. i++
  462. eneg = true
  463. }
  464. if i < slen {
  465. // for exact match, exponent is 1 or 2 digits (float64: -22 to 37, float32: -1 to 17).
  466. // exit quick if exponent is more than 2 digits.
  467. if i+2 < slen {
  468. return
  469. }
  470. var e int8
  471. if s[i] < '0' || s[i] > '9' { // !isDigitChar(s[i]) { //
  472. r.bad = true
  473. return
  474. }
  475. e = int8(s[i] - '0')
  476. i++
  477. if i < slen {
  478. if s[i] < '0' || s[i] > '9' { // !isDigitChar(s[i]) { //
  479. r.bad = true
  480. return
  481. }
  482. e = e*fBase + int8(s[i]-'0') // (e << 1) + (e << 3) + int8(s[i]-'0')
  483. i++
  484. }
  485. if eneg {
  486. dp -= e
  487. } else {
  488. dp += e
  489. }
  490. }
  491. }
  492. }
  493. if r.mantissa != 0 {
  494. r.exp = dp - ndMant
  495. // do not set ok=true for cases we cannot handle
  496. if r.exp < -y.exactPow10 ||
  497. r.exp > y.exactInts+y.exactPow10 ||
  498. y.mantbits != 0 && r.mantissa>>y.mantbits != 0 {
  499. return
  500. }
  501. }
  502. r.ok = true
  503. return
  504. }
  505. /*
  506. func parseUint64(b []byte) (f uint64, err error) {
  507. if b[0] == '-' {
  508. return 0, strconvParseErr(b, "ParseUint")
  509. }
  510. f, ok := parseUint64_simple(b)
  511. if !ok {
  512. return parseUint64_custom(b)
  513. }
  514. return
  515. }
  516. func parseInt64(b []byte) (v int64, err error) {
  517. // defer func() { xdebug2f("parseInt64: %s, return: %d, %v", b, v, err) }()
  518. // xdebugf("parseInt64: %s", b)
  519. var ok, neg bool
  520. var f uint64
  521. var r readFloatResult
  522. if b[0] == '-' {
  523. neg = true
  524. b = b[1:]
  525. }
  526. f, ok = parseUint64_simple(b)
  527. // xdebugf("parseuint64_simple: %v, %v", f, ok)
  528. if ok {
  529. if chkOvf.Uint2Int(f, neg) {
  530. goto ERROR
  531. }
  532. if neg {
  533. v = -int64(f)
  534. } else {
  535. v = int64(f)
  536. }
  537. return
  538. }
  539. r = readFloat(b, fi64i)
  540. // xdebugf("readFloat ok: %v", r.ok)
  541. if r.ok {
  542. r.neg = neg
  543. v, r.bad = parseInt64_reader(r)
  544. if r.bad {
  545. goto ERROR
  546. }
  547. return
  548. }
  549. ERROR:
  550. err = strconvParseErr(b, "ParseInt")
  551. return
  552. }
  553. func parseUint64_custom(b []byte) (f uint64, err error) {
  554. r := readFloat(b, fi64u)
  555. if r.ok {
  556. f, r.bad = parseUint64_reader(r)
  557. if r.bad {
  558. err = strconvParseErr(b, "ParseUint")
  559. }
  560. return
  561. }
  562. err = strconvParseErr(b, "ParseUint")
  563. return
  564. }
  565. func parseUint64_simple(b []byte) (n uint64, ok bool) {
  566. for _, c := range b {
  567. if c < '0' || c > '9' {
  568. return
  569. }
  570. // unsigned integers don't overflow well on multiplication, so check cutoff here
  571. // e.g. (maxUint64-5)*10 doesn't overflow well ...
  572. if n >= uint64Cutoff {
  573. return
  574. }
  575. n *= 10
  576. n1 := n + uint64(c-'0')
  577. if n1 < n {
  578. return
  579. }
  580. n = n1
  581. }
  582. ok = true
  583. return
  584. }
  585. func readFloat(s []byte, y floatinfo) (r readFloatResult) {
  586. // defer func() { xdebugf("readFloat: %#v", r) }()
  587. var i uint // uint, so that we eliminate bounds checking
  588. var slen = uint(len(s))
  589. if slen == 0 {
  590. // read an empty string as the zero value
  591. // r.bad = true
  592. r.ok = true
  593. return
  594. }
  595. if s[0] == '-' {
  596. r.neg = true
  597. i++
  598. }
  599. // we considered punting early if string has length > maxMantDigits, but this doesn't account
  600. // for trailing 0's e.g. 700000000000000000000 can be encoded exactly as it is 7e20
  601. // var mantCutoffIsUint64Cutoff bool
  602. // var mantCutoff uint64
  603. // if y.mantbits != 0 {
  604. // mantCutoff = 1<<y.mantbits - 1
  605. // } else if y.is32bit {
  606. // mantCutoff = fUint32Cutoff
  607. // } else {
  608. // mantCutoffIsUint64Cutoff = true
  609. // mantCutoff = fUint64Cutoff
  610. // }
  611. var nd, ndMant, dp int8
  612. var xu uint64
  613. var c uint8
  614. for ; i < slen; i++ {
  615. c = s[i]
  616. if c == '.' {
  617. if r.sawdot {
  618. r.bad = true
  619. return
  620. }
  621. r.sawdot = true
  622. dp = nd
  623. } else if c == 'e' || c == 'E' {
  624. r.sawexp = true
  625. break
  626. } else if c == '0' {
  627. if nd == 0 {
  628. dp--
  629. continue
  630. }
  631. nd++
  632. if r.mantissa < y.mantCutoff {
  633. r.mantissa *= fBase
  634. ndMant++
  635. }
  636. } else if isDigitChar(c) { // c >= '1' && c <= '9' { // !(c < '0' || c > '9') { //
  637. nd++
  638. if y.mantCutoffIsUint64Cutoff && r.mantissa < fUint64Cutoff {
  639. // mantissa = (mantissa << 1) + (mantissa << 3) + uint64(c-'0')
  640. r.mantissa *= fBase
  641. xu = r.mantissa + uint64(c-'0')
  642. if xu < r.mantissa {
  643. r.trunc = true
  644. return
  645. }
  646. r.mantissa = xu
  647. ndMant++
  648. } else if r.mantissa < y.mantCutoff {
  649. // mantissa = (mantissa << 1) + (mantissa << 3) + uint64(c-'0')
  650. r.mantissa = r.mantissa*fBase + uint64(c-'0')
  651. ndMant++
  652. } else {
  653. r.trunc = true
  654. return
  655. }
  656. // if r.mantissa < y.mantCutoff {
  657. // if y.mantCutoffIsUint64Cutoff {
  658. // // mantissa = (mantissa << 1) + (mantissa << 3) + uint64(c-'0')
  659. // r.mantissa *= fBase
  660. // xu = r.mantissa + uint64(c-'0')
  661. // if xu < r.mantissa {
  662. // r.trunc = true
  663. // return
  664. // }
  665. // r.mantissa = xu
  666. // } else {
  667. // // mantissa = (mantissa << 1) + (mantissa << 3) + uint64(c-'0')
  668. // r.mantissa = r.mantissa*fBase + uint64(c-'0')
  669. // }
  670. // ndMant++
  671. // } else {
  672. // r.trunc = true
  673. // return
  674. // }
  675. } else {
  676. r.bad = true
  677. return
  678. }
  679. }
  680. if !r.sawdot {
  681. dp = nd
  682. }
  683. if r.sawexp {
  684. i++
  685. if i < slen {
  686. var eneg bool
  687. if s[i] == '+' {
  688. i++
  689. } else if s[i] == '-' {
  690. i++
  691. eneg = true
  692. }
  693. if i < slen {
  694. // for exact match, exponent is 1 or 2 digits (float64: -22 to 37, float32: -1 to 17).
  695. // exit quick if exponent is more than 2 digits.
  696. if i+2 < slen {
  697. return
  698. }
  699. var e int8
  700. if !isDigitChar(s[i]) { // s[i] < '0' || s[i] > '9' {
  701. r.bad = true
  702. return
  703. }
  704. e = int8(s[i] - '0')
  705. i++
  706. if i < slen {
  707. if !isDigitChar(s[i]) { // s[i] < '0' || s[i] > '9' {
  708. r.bad = true
  709. return
  710. }
  711. e = e*fBase + int8(s[i]-'0') // (e << 1) + (e << 3) + int8(s[i]-'0')
  712. i++
  713. }
  714. if eneg {
  715. dp -= e
  716. } else {
  717. dp += e
  718. }
  719. }
  720. }
  721. }
  722. if r.mantissa != 0 {
  723. r.exp = dp - ndMant
  724. // do not set ok=true for cases we cannot handle
  725. if r.exp < -y.exactPow10 ||
  726. r.exp > y.exactInts+y.exactPow10 ||
  727. y.mantbits != 0 && r.mantissa>>y.mantbits != 0 {
  728. return
  729. }
  730. }
  731. r.ok = true
  732. return
  733. }
  734. */