ftoa.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. package ftoa
  2. import (
  3. "math"
  4. "math/big"
  5. )
  6. const (
  7. exp_11 = 0x3ff00000
  8. frac_mask1 = 0xfffff
  9. bletch = 0x10
  10. quick_max = 14
  11. int_max = 14
  12. )
  13. var (
  14. tens = [...]float64{
  15. 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
  16. 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
  17. 1e20, 1e21, 1e22,
  18. }
  19. bigtens = [...]float64{1e16, 1e32, 1e64, 1e128, 1e256}
  20. big5 = big.NewInt(5)
  21. big10 = big.NewInt(10)
  22. p05 = []*big.Int{big5, big.NewInt(25), big.NewInt(125)}
  23. pow5Cache [7]*big.Int
  24. dtoaModes = []int{
  25. ModeStandard: 0,
  26. ModeStandardExponential: 0,
  27. ModeFixed: 3,
  28. ModeExponential: 2,
  29. ModePrecision: 2,
  30. }
  31. )
  32. /*
  33. d must be > 0 and must not be Inf
  34. mode:
  35. 0 ==> shortest string that yields d when read in
  36. and rounded to nearest.
  37. 1 ==> like 0, but with Steele & White stopping rule;
  38. e.g. with IEEE P754 arithmetic , mode 0 gives
  39. 1e23 whereas mode 1 gives 9.999999999999999e22.
  40. 2 ==> max(1,ndigits) significant digits. This gives a
  41. return value similar to that of ecvt, except
  42. that trailing zeros are suppressed.
  43. 3 ==> through ndigits past the decimal point. This
  44. gives a return value similar to that from fcvt,
  45. except that trailing zeros are suppressed, and
  46. ndigits can be negative.
  47. 4,5 ==> similar to 2 and 3, respectively, but (in
  48. round-nearest mode) with the tests of mode 0 to
  49. possibly return a shorter string that rounds to d.
  50. With IEEE arithmetic and compilation with
  51. -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
  52. as modes 2 and 3 when FLT_ROUNDS != 1.
  53. 6-9 ==> Debugging modes similar to mode - 4: don't try
  54. fast floating-point estimate (if applicable).
  55. Values of mode other than 0-9 are treated as mode 0.
  56. */
  57. func ftoa(d float64, mode int, biasUp bool, ndigits int, buf []byte) ([]byte, int) {
  58. startPos := len(buf)
  59. dblBits := make([]byte, 0, 8)
  60. be, bbits, dblBits := d2b(d, dblBits)
  61. dBits := math.Float64bits(d)
  62. word0 := uint32(dBits >> 32)
  63. word1 := uint32(dBits)
  64. i := int((word0 >> exp_shift1) & (exp_mask >> exp_shift1))
  65. var d2 float64
  66. var denorm bool
  67. if i != 0 {
  68. d2 = setWord0(d, (word0&frac_mask1)|exp_11)
  69. i -= bias
  70. denorm = false
  71. } else {
  72. /* d is denormalized */
  73. i = bbits + be + (bias + (p - 1) - 1)
  74. var x uint64
  75. if i > 32 {
  76. x = uint64(word0)<<(64-i) | uint64(word1)>>(i-32)
  77. } else {
  78. x = uint64(word1) << (32 - i)
  79. }
  80. d2 = setWord0(float64(x), uint32((x>>32)-31*exp_mask))
  81. i -= (bias + (p - 1) - 1) + 1
  82. denorm = true
  83. }
  84. /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */
  85. ds := (d2-1.5)*0.289529654602168 + 0.1760912590558 + float64(i)*0.301029995663981
  86. k := int(ds)
  87. if ds < 0.0 && ds != float64(k) {
  88. k-- /* want k = floor(ds) */
  89. }
  90. k_check := true
  91. if k >= 0 && k < len(tens) {
  92. if d < tens[k] {
  93. k--
  94. }
  95. k_check = false
  96. }
  97. /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.
  98. If k_check is zero, we're guaranteed that k = floor(log10(d)). */
  99. j := bbits - i - 1
  100. var b2, s2, b5, s5 int
  101. /* At this point d = b/2^j, where b is an odd integer. */
  102. if j >= 0 {
  103. b2 = 0
  104. s2 = j
  105. } else {
  106. b2 = -j
  107. s2 = 0
  108. }
  109. if k >= 0 {
  110. b5 = 0
  111. s5 = k
  112. s2 += k
  113. } else {
  114. b2 -= k
  115. b5 = -k
  116. s5 = 0
  117. }
  118. /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,
  119. b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */
  120. if mode < 0 || mode > 9 {
  121. mode = 0
  122. }
  123. try_quick := true
  124. if mode > 5 {
  125. mode -= 4
  126. try_quick = false
  127. }
  128. leftright := true
  129. var ilim, ilim1 int
  130. switch mode {
  131. case 0, 1:
  132. ilim, ilim1 = -1, -1
  133. ndigits = 0
  134. case 2:
  135. leftright = false
  136. fallthrough
  137. case 4:
  138. if ndigits <= 0 {
  139. ndigits = 1
  140. }
  141. ilim, ilim1 = ndigits, ndigits
  142. case 3:
  143. leftright = false
  144. fallthrough
  145. case 5:
  146. i = ndigits + k + 1
  147. ilim = i
  148. ilim1 = i - 1
  149. }
  150. /* ilim is the maximum number of significant digits we want, based on k and ndigits. */
  151. /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,
  152. when it turns out that k was computed too high by one. */
  153. fast_failed := false
  154. if ilim >= 0 && ilim <= quick_max && try_quick {
  155. /* Try to get by with floating-point arithmetic. */
  156. i = 0
  157. d2 = d
  158. k0 := k
  159. ilim0 := ilim
  160. ieps := 2 /* conservative */
  161. /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */
  162. if k > 0 {
  163. ds = tens[k&0xf]
  164. j = k >> 4
  165. if (j & bletch) != 0 {
  166. /* prevent overflows */
  167. j &= bletch - 1
  168. d /= bigtens[len(bigtens)-1]
  169. ieps++
  170. }
  171. for ; j != 0; i++ {
  172. if (j & 1) != 0 {
  173. ieps++
  174. ds *= bigtens[i]
  175. }
  176. j >>= 1
  177. }
  178. d /= ds
  179. } else if j1 := -k; j1 != 0 {
  180. d *= tens[j1&0xf]
  181. for j = j1 >> 4; j != 0; i++ {
  182. if (j & 1) != 0 {
  183. ieps++
  184. d *= bigtens[i]
  185. }
  186. j >>= 1
  187. }
  188. }
  189. /* Check that k was computed correctly. */
  190. if k_check && d < 1.0 && ilim > 0 {
  191. if ilim1 <= 0 {
  192. fast_failed = true
  193. } else {
  194. ilim = ilim1
  195. k--
  196. d *= 10.
  197. ieps++
  198. }
  199. }
  200. /* eps bounds the cumulative error. */
  201. eps := float64(ieps)*d + 7.0
  202. eps = setWord0(eps, _word0(eps)-(p-1)*exp_msk1)
  203. if ilim == 0 {
  204. d -= 5.0
  205. if d > eps {
  206. buf = append(buf, '1')
  207. k++
  208. return buf, k + 1
  209. }
  210. if d < -eps {
  211. buf = append(buf, '0')
  212. return buf, 1
  213. }
  214. fast_failed = true
  215. }
  216. if !fast_failed {
  217. fast_failed = true
  218. if leftright {
  219. /* Use Steele & White method of only
  220. * generating digits needed.
  221. */
  222. eps = 0.5/tens[ilim-1] - eps
  223. for i = 0; ; {
  224. l := int64(d)
  225. d -= float64(l)
  226. buf = append(buf, byte('0'+l))
  227. if d < eps {
  228. return buf, k + 1
  229. }
  230. if 1.0-d < eps {
  231. buf, k = bumpUp(buf, k)
  232. return buf, k + 1
  233. }
  234. i++
  235. if i >= ilim {
  236. break
  237. }
  238. eps *= 10.0
  239. d *= 10.0
  240. }
  241. } else {
  242. /* Generate ilim digits, then fix them up. */
  243. eps *= tens[ilim-1]
  244. for i = 1; ; i++ {
  245. l := int64(d)
  246. d -= float64(l)
  247. buf = append(buf, byte('0'+l))
  248. if i == ilim {
  249. if d > 0.5+eps {
  250. buf, k = bumpUp(buf, k)
  251. return buf, k + 1
  252. } else if d < 0.5-eps {
  253. buf = stripTrailingZeroes(buf, startPos)
  254. return buf, k + 1
  255. }
  256. break
  257. }
  258. d *= 10.0
  259. }
  260. }
  261. }
  262. if fast_failed {
  263. buf = buf[:startPos]
  264. d = d2
  265. k = k0
  266. ilim = ilim0
  267. }
  268. }
  269. /* Do we have a "small" integer? */
  270. if be >= 0 && k <= int_max {
  271. /* Yes. */
  272. ds = tens[k]
  273. if ndigits < 0 && ilim <= 0 {
  274. if ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds) {
  275. buf = buf[:startPos]
  276. buf = append(buf, '0')
  277. return buf, 1
  278. }
  279. buf = append(buf, '1')
  280. k++
  281. return buf, k + 1
  282. }
  283. for i = 1; ; i++ {
  284. l := int64(d / ds)
  285. d -= float64(l) * ds
  286. buf = append(buf, byte('0'+l))
  287. if i == ilim {
  288. d += d
  289. if (d > ds) || (d == ds && (((l & 1) != 0) || biasUp)) {
  290. buf, k = bumpUp(buf, k)
  291. }
  292. break
  293. }
  294. d *= 10.0
  295. if d == 0 {
  296. break
  297. }
  298. }
  299. return buf, k + 1
  300. }
  301. m2 := b2
  302. m5 := b5
  303. var mhi, mlo *big.Int
  304. if leftright {
  305. if mode < 2 {
  306. if denorm {
  307. i = be + (bias + (p - 1) - 1 + 1)
  308. } else {
  309. i = 1 + p - bbits
  310. }
  311. /* i is 1 plus the number of trailing zero bits in d's significand. Thus,
  312. (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */
  313. } else {
  314. j = ilim - 1
  315. if m5 >= j {
  316. m5 -= j
  317. } else {
  318. j -= m5
  319. s5 += j
  320. b5 += j
  321. m5 = 0
  322. }
  323. i = ilim
  324. if i < 0 {
  325. m2 -= i
  326. i = 0
  327. }
  328. /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */
  329. }
  330. b2 += i
  331. s2 += i
  332. mhi = big.NewInt(1)
  333. /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or
  334. input (when mode < 2) significant digit, divided by 10^k. */
  335. }
  336. /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in
  337. b2, m2, and s2 without changing the equalities. */
  338. if m2 > 0 && s2 > 0 {
  339. if m2 < s2 {
  340. i = m2
  341. } else {
  342. i = s2
  343. }
  344. b2 -= i
  345. m2 -= i
  346. s2 -= i
  347. }
  348. b := new(big.Int).SetBytes(dblBits)
  349. /* Fold b5 into b and m5 into mhi. */
  350. if b5 > 0 {
  351. if leftright {
  352. if m5 > 0 {
  353. pow5mult(mhi, m5)
  354. b.Mul(mhi, b)
  355. }
  356. j = b5 - m5
  357. if j != 0 {
  358. pow5mult(b, j)
  359. }
  360. } else {
  361. pow5mult(b, b5)
  362. }
  363. }
  364. /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and
  365. (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */
  366. S := big.NewInt(1)
  367. if s5 > 0 {
  368. pow5mult(S, s5)
  369. }
  370. /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and
  371. (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */
  372. /* Check for special case that d is a normalized power of 2. */
  373. spec_case := false
  374. if mode < 2 {
  375. if (_word1(d) == 0) && ((_word0(d) & bndry_mask) == 0) &&
  376. ((_word0(d) & (exp_mask & (exp_mask << 1))) != 0) {
  377. /* The special case. Here we want to be within a quarter of the last input
  378. significant digit instead of one half of it when the decimal output string's value is less than d. */
  379. b2 += log2P
  380. s2 += log2P
  381. spec_case = true
  382. }
  383. }
  384. /* Arrange for convenient computation of quotients:
  385. * shift left if necessary so divisor has 4 leading 0 bits.
  386. *
  387. * Perhaps we should just compute leading 28 bits of S once
  388. * and for all and pass them and a shift to quorem, so it
  389. * can do shifts and ors to compute the numerator for q.
  390. */
  391. var zz int
  392. if s5 != 0 {
  393. S_bytes := S.Bytes()
  394. var S_hiWord uint32
  395. for idx := 0; idx < 4; idx++ {
  396. S_hiWord = S_hiWord << 8
  397. if idx < len(S_bytes) {
  398. S_hiWord |= uint32(S_bytes[idx])
  399. }
  400. }
  401. zz = 32 - hi0bits(S_hiWord)
  402. } else {
  403. zz = 1
  404. }
  405. i = (zz + s2) & 0x1f
  406. if i != 0 {
  407. i = 32 - i
  408. }
  409. /* i is the number of leading zero bits in the most significant word of S*2^s2. */
  410. if i > 4 {
  411. i -= 4
  412. b2 += i
  413. m2 += i
  414. s2 += i
  415. } else if i < 4 {
  416. i += 28
  417. b2 += i
  418. m2 += i
  419. s2 += i
  420. }
  421. /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */
  422. if b2 > 0 {
  423. b = b.Lsh(b, uint(b2))
  424. }
  425. if s2 > 0 {
  426. S.Lsh(S, uint(s2))
  427. }
  428. /* Now we have d/10^k = b/S and
  429. (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */
  430. if k_check {
  431. if b.Cmp(S) < 0 {
  432. k--
  433. b.Mul(b, big10) /* we botched the k estimate */
  434. if leftright {
  435. mhi.Mul(mhi, big10)
  436. }
  437. ilim = ilim1
  438. }
  439. }
  440. /* At this point 1 <= d/10^k = b/S < 10. */
  441. if ilim <= 0 && mode > 2 {
  442. /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.
  443. Output either zero or the minimum nonzero output depending on which is closer to d. */
  444. if ilim >= 0 {
  445. i = b.Cmp(S.Mul(S, big5))
  446. }
  447. if ilim < 0 || i < 0 || i == 0 && !biasUp {
  448. /* Always emit at least one digit. If the number appears to be zero
  449. using the current mode, then emit one '0' digit and set decpt to 1. */
  450. buf = buf[:startPos]
  451. buf = append(buf, '0')
  452. return buf, 1
  453. }
  454. buf = append(buf, '1')
  455. k++
  456. return buf, k + 1
  457. }
  458. var dig byte
  459. if leftright {
  460. if m2 > 0 {
  461. mhi.Lsh(mhi, uint(m2))
  462. }
  463. /* Compute mlo -- check for special case
  464. * that d is a normalized power of 2.
  465. */
  466. mlo = mhi
  467. if spec_case {
  468. mhi = mlo
  469. mhi = new(big.Int).Lsh(mhi, log2P)
  470. }
  471. /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */
  472. /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */
  473. var z, delta big.Int
  474. for i = 1; ; i++ {
  475. z.DivMod(b, S, b)
  476. dig = byte(z.Int64() + '0')
  477. /* Do we yet have the shortest decimal string
  478. * that will round to d?
  479. */
  480. j = b.Cmp(mlo)
  481. /* j is b/S compared with mlo/S. */
  482. delta.Sub(S, mhi)
  483. var j1 int
  484. if delta.Sign() <= 0 {
  485. j1 = 1
  486. } else {
  487. j1 = b.Cmp(&delta)
  488. }
  489. /* j1 is b/S compared with 1 - mhi/S. */
  490. if (j1 == 0) && (mode == 0) && ((_word1(d) & 1) == 0) {
  491. if dig == '9' {
  492. var flag bool
  493. buf = append(buf, '9')
  494. if buf, flag = roundOff(buf, startPos); flag {
  495. k++
  496. buf = append(buf, '1')
  497. }
  498. return buf, k + 1
  499. }
  500. if j > 0 {
  501. dig++
  502. }
  503. buf = append(buf, dig)
  504. return buf, k + 1
  505. }
  506. if (j < 0) || ((j == 0) && (mode == 0) && ((_word1(d) & 1) == 0)) {
  507. if j1 > 0 {
  508. /* Either dig or dig+1 would work here as the least significant decimal digit.
  509. Use whichever would produce a decimal value closer to d. */
  510. b.Lsh(b, 1)
  511. j1 = b.Cmp(S)
  512. if (j1 > 0) || (j1 == 0 && (((dig & 1) == 1) || biasUp)) {
  513. dig++
  514. if dig == '9' {
  515. buf = append(buf, '9')
  516. buf, flag := roundOff(buf, startPos)
  517. if flag {
  518. k++
  519. buf = append(buf, '1')
  520. }
  521. return buf, k + 1
  522. }
  523. }
  524. }
  525. buf = append(buf, dig)
  526. return buf, k + 1
  527. }
  528. if j1 > 0 {
  529. if dig == '9' { /* possible if i == 1 */
  530. buf = append(buf, '9')
  531. buf, flag := roundOff(buf, startPos)
  532. if flag {
  533. k++
  534. buf = append(buf, '1')
  535. }
  536. return buf, k + 1
  537. }
  538. buf = append(buf, dig+1)
  539. return buf, k + 1
  540. }
  541. buf = append(buf, dig)
  542. if i == ilim {
  543. break
  544. }
  545. b.Mul(b, big10)
  546. if mlo == mhi {
  547. mhi.Mul(mhi, big10)
  548. } else {
  549. mlo.Mul(mlo, big10)
  550. mhi.Mul(mhi, big10)
  551. }
  552. }
  553. } else {
  554. var z big.Int
  555. for i = 1; ; i++ {
  556. z.DivMod(b, S, b)
  557. dig = byte(z.Int64() + '0')
  558. buf = append(buf, dig)
  559. if i >= ilim {
  560. break
  561. }
  562. b.Mul(b, big10)
  563. }
  564. }
  565. /* Round off last digit */
  566. b.Lsh(b, 1)
  567. j = b.Cmp(S)
  568. if (j > 0) || (j == 0 && (((dig & 1) == 1) || biasUp)) {
  569. var flag bool
  570. buf, flag = roundOff(buf, startPos)
  571. if flag {
  572. k++
  573. buf = append(buf, '1')
  574. return buf, k + 1
  575. }
  576. } else {
  577. buf = stripTrailingZeroes(buf, startPos)
  578. }
  579. return buf, k + 1
  580. }
  581. func bumpUp(buf []byte, k int) ([]byte, int) {
  582. var lastCh byte
  583. stop := 0
  584. if len(buf) > 0 && buf[0] == '-' {
  585. stop = 1
  586. }
  587. for {
  588. lastCh = buf[len(buf)-1]
  589. buf = buf[:len(buf)-1]
  590. if lastCh != '9' {
  591. break
  592. }
  593. if len(buf) == stop {
  594. k++
  595. lastCh = '0'
  596. break
  597. }
  598. }
  599. buf = append(buf, lastCh+1)
  600. return buf, k
  601. }
  602. func setWord0(d float64, w uint32) float64 {
  603. dBits := math.Float64bits(d)
  604. return math.Float64frombits(uint64(w)<<32 | dBits&0xffffffff)
  605. }
  606. func _word0(d float64) uint32 {
  607. dBits := math.Float64bits(d)
  608. return uint32(dBits >> 32)
  609. }
  610. func _word1(d float64) uint32 {
  611. dBits := math.Float64bits(d)
  612. return uint32(dBits)
  613. }
  614. func stripTrailingZeroes(buf []byte, startPos int) []byte {
  615. bl := len(buf) - 1
  616. for bl >= startPos && buf[bl] == '0' {
  617. bl--
  618. }
  619. return buf[:bl+1]
  620. }
  621. /* Set b = b * 5^k. k must be nonnegative. */
  622. func pow5mult(b *big.Int, k int) *big.Int {
  623. if k < (1 << (len(pow5Cache) + 2)) {
  624. i := k & 3
  625. if i != 0 {
  626. b.Mul(b, p05[i-1])
  627. }
  628. k >>= 2
  629. i = 0
  630. for {
  631. if k&1 != 0 {
  632. b.Mul(b, pow5Cache[i])
  633. }
  634. k >>= 1
  635. if k == 0 {
  636. break
  637. }
  638. i++
  639. }
  640. return b
  641. }
  642. return b.Mul(b, new(big.Int).Exp(big5, big.NewInt(int64(k)), nil))
  643. }
  644. func roundOff(buf []byte, startPos int) ([]byte, bool) {
  645. i := len(buf)
  646. for i != startPos {
  647. i--
  648. if buf[i] != '9' {
  649. buf[i]++
  650. return buf[:i+1], false
  651. }
  652. }
  653. return buf[:startPos], true
  654. }
  655. func init() {
  656. p := big.NewInt(625)
  657. pow5Cache[0] = p
  658. for i := 1; i < len(pow5Cache); i++ {
  659. p = new(big.Int).Mul(p, p)
  660. pow5Cache[i] = p
  661. }
  662. }