ftoa.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. package v1
  2. /**
  3. * Copyright 2015 Paul Querna, Klaus Post
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. /* Most of this file are on Go stdlib's strconv/ftoa.go */
  19. // Copyright 2009 The Go Authors. All rights reserved.
  20. // Use of this source code is governed by a BSD-style
  21. // license that can be found in the LICENSE file.
  22. import "math"
  23. // TODO: move elsewhere?
  24. type floatInfo struct {
  25. mantbits uint
  26. expbits uint
  27. bias int
  28. }
  29. var optimize = true // can change for testing
  30. var float32info = floatInfo{23, 8, -127}
  31. var float64info = floatInfo{52, 11, -1023}
  32. // AppendFloat appends the string form of the floating-point number f,
  33. // as generated by FormatFloat
  34. func AppendFloat(dst EncodingBuffer, val float64, fmt byte, prec, bitSize int) {
  35. var bits uint64
  36. var flt *floatInfo
  37. switch bitSize {
  38. case 32:
  39. bits = uint64(math.Float32bits(float32(val)))
  40. flt = &float32info
  41. case 64:
  42. bits = math.Float64bits(val)
  43. flt = &float64info
  44. default:
  45. panic("strconv: illegal AppendFloat/FormatFloat bitSize")
  46. }
  47. neg := bits>>(flt.expbits+flt.mantbits) != 0
  48. exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
  49. mant := bits & (uint64(1)<<flt.mantbits - 1)
  50. switch exp {
  51. case 1<<flt.expbits - 1:
  52. // Inf, NaN
  53. var s string
  54. switch {
  55. case mant != 0:
  56. s = "NaN"
  57. case neg:
  58. s = "-Inf"
  59. default:
  60. s = "+Inf"
  61. }
  62. dst.WriteString(s)
  63. return
  64. case 0:
  65. // denormalized
  66. exp++
  67. default:
  68. // add implicit top bit
  69. mant |= uint64(1) << flt.mantbits
  70. }
  71. exp += flt.bias
  72. // Pick off easy binary format.
  73. if fmt == 'b' {
  74. fmtB(dst, neg, mant, exp, flt)
  75. return
  76. }
  77. if !optimize {
  78. bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
  79. return
  80. }
  81. var digs decimalSlice
  82. ok := false
  83. // Negative precision means "only as much as needed to be exact."
  84. shortest := prec < 0
  85. if shortest {
  86. // Try Grisu3 algorithm.
  87. f := new(extFloat)
  88. lower, upper := f.AssignComputeBounds(mant, exp, neg, flt)
  89. var buf [32]byte
  90. digs.d = buf[:]
  91. ok = f.ShortestDecimal(&digs, &lower, &upper)
  92. if !ok {
  93. bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
  94. return
  95. }
  96. // Precision for shortest representation mode.
  97. switch fmt {
  98. case 'e', 'E':
  99. prec = max(digs.nd-1, 0)
  100. case 'f':
  101. prec = max(digs.nd-digs.dp, 0)
  102. case 'g', 'G':
  103. prec = digs.nd
  104. }
  105. } else if fmt != 'f' {
  106. // Fixed number of digits.
  107. digits := prec
  108. switch fmt {
  109. case 'e', 'E':
  110. digits++
  111. case 'g', 'G':
  112. if prec == 0 {
  113. prec = 1
  114. }
  115. digits = prec
  116. }
  117. if digits <= 15 {
  118. // try fast algorithm when the number of digits is reasonable.
  119. var buf [24]byte
  120. digs.d = buf[:]
  121. f := extFloat{mant, exp - int(flt.mantbits), neg}
  122. ok = f.FixedDecimal(&digs, digits)
  123. }
  124. }
  125. if !ok {
  126. bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
  127. return
  128. }
  129. formatDigits(dst, shortest, neg, digs, prec, fmt)
  130. return
  131. }
  132. // bigFtoa uses multiprecision computations to format a float.
  133. func bigFtoa(dst EncodingBuffer, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) {
  134. d := new(decimal)
  135. d.Assign(mant)
  136. d.Shift(exp - int(flt.mantbits))
  137. var digs decimalSlice
  138. shortest := prec < 0
  139. if shortest {
  140. roundShortest(d, mant, exp, flt)
  141. digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
  142. // Precision for shortest representation mode.
  143. switch fmt {
  144. case 'e', 'E':
  145. prec = digs.nd - 1
  146. case 'f':
  147. prec = max(digs.nd-digs.dp, 0)
  148. case 'g', 'G':
  149. prec = digs.nd
  150. }
  151. } else {
  152. // Round appropriately.
  153. switch fmt {
  154. case 'e', 'E':
  155. d.Round(prec + 1)
  156. case 'f':
  157. d.Round(d.dp + prec)
  158. case 'g', 'G':
  159. if prec == 0 {
  160. prec = 1
  161. }
  162. d.Round(prec)
  163. }
  164. digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
  165. }
  166. formatDigits(dst, shortest, neg, digs, prec, fmt)
  167. return
  168. }
  169. func formatDigits(dst EncodingBuffer, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) {
  170. switch fmt {
  171. case 'e', 'E':
  172. fmtE(dst, neg, digs, prec, fmt)
  173. return
  174. case 'f':
  175. fmtF(dst, neg, digs, prec)
  176. return
  177. case 'g', 'G':
  178. // trailing fractional zeros in 'e' form will be trimmed.
  179. eprec := prec
  180. if eprec > digs.nd && digs.nd >= digs.dp {
  181. eprec = digs.nd
  182. }
  183. // %e is used if the exponent from the conversion
  184. // is less than -4 or greater than or equal to the precision.
  185. // if precision was the shortest possible, use precision 6 for this decision.
  186. if shortest {
  187. eprec = 6
  188. }
  189. exp := digs.dp - 1
  190. if exp < -4 || exp >= eprec {
  191. if prec > digs.nd {
  192. prec = digs.nd
  193. }
  194. fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
  195. return
  196. }
  197. if prec > digs.dp {
  198. prec = digs.nd
  199. }
  200. fmtF(dst, neg, digs, max(prec-digs.dp, 0))
  201. return
  202. }
  203. // unknown format
  204. dst.Write([]byte{'%', fmt})
  205. return
  206. }
  207. // Round d (= mant * 2^exp) to the shortest number of digits
  208. // that will let the original floating point value be precisely
  209. // reconstructed. Size is original floating point size (64 or 32).
  210. func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
  211. // If mantissa is zero, the number is zero; stop now.
  212. if mant == 0 {
  213. d.nd = 0
  214. return
  215. }
  216. // Compute upper and lower such that any decimal number
  217. // between upper and lower (possibly inclusive)
  218. // will round to the original floating point number.
  219. // We may see at once that the number is already shortest.
  220. //
  221. // Suppose d is not denormal, so that 2^exp <= d < 10^dp.
  222. // The closest shorter number is at least 10^(dp-nd) away.
  223. // The lower/upper bounds computed below are at distance
  224. // at most 2^(exp-mantbits).
  225. //
  226. // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
  227. // or equivalently log2(10)*(dp-nd) > exp-mantbits.
  228. // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
  229. minexp := flt.bias + 1 // minimum possible exponent
  230. if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
  231. // The number is already shortest.
  232. return
  233. }
  234. // d = mant << (exp - mantbits)
  235. // Next highest floating point number is mant+1 << exp-mantbits.
  236. // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
  237. upper := new(decimal)
  238. upper.Assign(mant*2 + 1)
  239. upper.Shift(exp - int(flt.mantbits) - 1)
  240. // d = mant << (exp - mantbits)
  241. // Next lowest floating point number is mant-1 << exp-mantbits,
  242. // unless mant-1 drops the significant bit and exp is not the minimum exp,
  243. // in which case the next lowest is mant*2-1 << exp-mantbits-1.
  244. // Either way, call it mantlo << explo-mantbits.
  245. // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
  246. var mantlo uint64
  247. var explo int
  248. if mant > 1<<flt.mantbits || exp == minexp {
  249. mantlo = mant - 1
  250. explo = exp
  251. } else {
  252. mantlo = mant*2 - 1
  253. explo = exp - 1
  254. }
  255. lower := new(decimal)
  256. lower.Assign(mantlo*2 + 1)
  257. lower.Shift(explo - int(flt.mantbits) - 1)
  258. // The upper and lower bounds are possible outputs only if
  259. // the original mantissa is even, so that IEEE round-to-even
  260. // would round to the original mantissa and not the neighbors.
  261. inclusive := mant%2 == 0
  262. // Now we can figure out the minimum number of digits required.
  263. // Walk along until d has distinguished itself from upper and lower.
  264. for i := 0; i < d.nd; i++ {
  265. var l, m, u byte // lower, middle, upper digits
  266. if i < lower.nd {
  267. l = lower.d[i]
  268. } else {
  269. l = '0'
  270. }
  271. m = d.d[i]
  272. if i < upper.nd {
  273. u = upper.d[i]
  274. } else {
  275. u = '0'
  276. }
  277. // Okay to round down (truncate) if lower has a different digit
  278. // or if lower is inclusive and is exactly the result of rounding down.
  279. okdown := l != m || (inclusive && l == m && i+1 == lower.nd)
  280. // Okay to round up if upper has a different digit and
  281. // either upper is inclusive or upper is bigger than the result of rounding up.
  282. okup := m != u && (inclusive || m+1 < u || i+1 < upper.nd)
  283. // If it's okay to do either, then round to the nearest one.
  284. // If it's okay to do only one, do it.
  285. switch {
  286. case okdown && okup:
  287. d.Round(i + 1)
  288. return
  289. case okdown:
  290. d.RoundDown(i + 1)
  291. return
  292. case okup:
  293. d.RoundUp(i + 1)
  294. return
  295. }
  296. }
  297. }
  298. type decimalSlice struct {
  299. d []byte
  300. nd, dp int
  301. neg bool
  302. }
  303. // %e: -d.ddddde±dd
  304. func fmtE(dst EncodingBuffer, neg bool, d decimalSlice, prec int, fmt byte) {
  305. // sign
  306. if neg {
  307. dst.WriteByte('-')
  308. }
  309. // first digit
  310. ch := byte('0')
  311. if d.nd != 0 {
  312. ch = d.d[0]
  313. }
  314. dst.WriteByte(ch)
  315. // .moredigits
  316. if prec > 0 {
  317. dst.WriteByte('.')
  318. i := 1
  319. m := min(d.nd, prec+1)
  320. if i < m {
  321. dst.Write(d.d[i:m])
  322. i = m
  323. }
  324. for i <= prec {
  325. dst.WriteByte('0')
  326. i++
  327. }
  328. }
  329. // e±
  330. dst.WriteByte(fmt)
  331. exp := d.dp - 1
  332. if d.nd == 0 { // special case: 0 has exponent 0
  333. exp = 0
  334. }
  335. if exp < 0 {
  336. ch = '-'
  337. exp = -exp
  338. } else {
  339. ch = '+'
  340. }
  341. dst.WriteByte(ch)
  342. // dd or ddd
  343. switch {
  344. case exp < 10:
  345. dst.WriteByte('0')
  346. dst.WriteByte(byte(exp) + '0')
  347. case exp < 100:
  348. dst.WriteByte(byte(exp/10) + '0')
  349. dst.WriteByte(byte(exp%10) + '0')
  350. default:
  351. dst.WriteByte(byte(exp/100) + '0')
  352. dst.WriteByte(byte(exp/10)%10 + '0')
  353. dst.WriteByte(byte(exp%10) + '0')
  354. }
  355. return
  356. }
  357. // %f: -ddddddd.ddddd
  358. func fmtF(dst EncodingBuffer, neg bool, d decimalSlice, prec int) {
  359. // sign
  360. if neg {
  361. dst.WriteByte('-')
  362. }
  363. // integer, padded with zeros as needed.
  364. if d.dp > 0 {
  365. m := min(d.nd, d.dp)
  366. dst.Write(d.d[:m])
  367. for ; m < d.dp; m++ {
  368. dst.WriteByte('0')
  369. }
  370. } else {
  371. dst.WriteByte('0')
  372. }
  373. // fraction
  374. if prec > 0 {
  375. dst.WriteByte('.')
  376. for i := 0; i < prec; i++ {
  377. ch := byte('0')
  378. if j := d.dp + i; 0 <= j && j < d.nd {
  379. ch = d.d[j]
  380. }
  381. dst.WriteByte(ch)
  382. }
  383. }
  384. return
  385. }
  386. // %b: -ddddddddp±ddd
  387. func fmtB(dst EncodingBuffer, neg bool, mant uint64, exp int, flt *floatInfo) {
  388. // sign
  389. if neg {
  390. dst.WriteByte('-')
  391. }
  392. // mantissa
  393. formatBits(dst, mant, 10, false)
  394. // p
  395. dst.WriteByte('p')
  396. // ±exponent
  397. exp -= int(flt.mantbits)
  398. if exp >= 0 {
  399. dst.WriteByte('+')
  400. }
  401. formatBits(dst, uint64(exp), 10, exp < 0)
  402. return
  403. }
  404. func min(a, b int) int {
  405. if a < b {
  406. return a
  407. }
  408. return b
  409. }
  410. func max(a, b int) int {
  411. if a > b {
  412. return a
  413. }
  414. return b
  415. }
  416. // formatBits computes the string representation of u in the given base.
  417. // If neg is set, u is treated as negative int64 value.
  418. func formatBits(dst EncodingBuffer, u uint64, base int, neg bool) {
  419. if base < 2 || base > len(digits) {
  420. panic("strconv: illegal AppendInt/FormatInt base")
  421. }
  422. // 2 <= base && base <= len(digits)
  423. var a [64 + 1]byte // +1 for sign of 64bit value in base 2
  424. i := len(a)
  425. if neg {
  426. u = -u
  427. }
  428. // convert bits
  429. if base == 10 {
  430. // common case: use constants for / because
  431. // the compiler can optimize it into a multiply+shift
  432. if ^uintptr(0)>>32 == 0 {
  433. for u > uint64(^uintptr(0)) {
  434. q := u / 1e9
  435. us := uintptr(u - q*1e9) // us % 1e9 fits into a uintptr
  436. for j := 9; j > 0; j-- {
  437. i--
  438. qs := us / 10
  439. a[i] = byte(us - qs*10 + '0')
  440. us = qs
  441. }
  442. u = q
  443. }
  444. }
  445. // u guaranteed to fit into a uintptr
  446. us := uintptr(u)
  447. for us >= 10 {
  448. i--
  449. q := us / 10
  450. a[i] = byte(us - q*10 + '0')
  451. us = q
  452. }
  453. // u < 10
  454. i--
  455. a[i] = byte(us + '0')
  456. } else if s := shifts[base]; s > 0 {
  457. // base is power of 2: use shifts and masks instead of / and %
  458. b := uint64(base)
  459. m := uintptr(b) - 1 // == 1<<s - 1
  460. for u >= b {
  461. i--
  462. a[i] = digits[uintptr(u)&m]
  463. u >>= s
  464. }
  465. // u < base
  466. i--
  467. a[i] = digits[uintptr(u)]
  468. } else {
  469. // general case
  470. b := uint64(base)
  471. for u >= b {
  472. i--
  473. q := u / b
  474. a[i] = digits[uintptr(u-q*b)]
  475. u = q
  476. }
  477. // u < base
  478. i--
  479. a[i] = digits[uintptr(u)]
  480. }
  481. // add sign, if any
  482. if neg {
  483. i--
  484. a[i] = '-'
  485. }
  486. dst.Write(a[i:])
  487. }