ftoa.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Binary to decimal floating point conversion.
  5. // Algorithm:
  6. // 1) store mantissa in multiprecision decimal
  7. // 2) shift decimal by exponent
  8. // 3) read digits out & format
  9. package strconv
  10. import "math"
  11. // TODO: move elsewhere?
  12. type floatInfo struct {
  13. mantbits uint
  14. expbits uint
  15. bias int
  16. }
  17. var float32info = floatInfo{23, 8, -127}
  18. var float64info = floatInfo{52, 11, -1023}
  19. // FormatFloat converts the floating-point number f to a string,
  20. // according to the format fmt and precision prec. It rounds the
  21. // result assuming that the original was obtained from a floating-point
  22. // value of bitSize bits (32 for float32, 64 for float64).
  23. //
  24. // The format fmt is one of
  25. // 'b' (-ddddp±ddd, a binary exponent),
  26. // 'e' (-d.dddde±dd, a decimal exponent),
  27. // 'E' (-d.ddddE±dd, a decimal exponent),
  28. // 'f' (-ddd.dddd, no exponent),
  29. // 'g' ('e' for large exponents, 'f' otherwise), or
  30. // 'G' ('E' for large exponents, 'f' otherwise).
  31. //
  32. // The precision prec controls the number of digits
  33. // (excluding the exponent) printed by the 'e', 'E', 'f', 'g', and 'G' formats.
  34. // For 'e', 'E', and 'f' it is the number of digits after the decimal point.
  35. // For 'g' and 'G' it is the total number of digits.
  36. // The special precision -1 uses the smallest number of digits
  37. // necessary such that ParseFloat will return f exactly.
  38. func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
  39. return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize))
  40. }
  41. // AppendFloat appends the string form of the floating-point number f,
  42. // as generated by FormatFloat, to dst and returns the extended buffer.
  43. func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte {
  44. return genericFtoa(dst, f, fmt, prec, bitSize)
  45. }
  46. func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
  47. var bits uint64
  48. var flt *floatInfo
  49. switch bitSize {
  50. case 32:
  51. bits = uint64(math.Float32bits(float32(val)))
  52. flt = &float32info
  53. case 64:
  54. bits = math.Float64bits(val)
  55. flt = &float64info
  56. default:
  57. panic("strconv: illegal AppendFloat/FormatFloat bitSize")
  58. }
  59. neg := bits>>(flt.expbits+flt.mantbits) != 0
  60. exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
  61. mant := bits & (uint64(1)<<flt.mantbits - 1)
  62. switch exp {
  63. case 1<<flt.expbits - 1:
  64. // Inf, NaN
  65. var s string
  66. switch {
  67. case mant != 0:
  68. s = "NaN"
  69. case neg:
  70. s = "-Inf"
  71. default:
  72. s = "+Inf"
  73. }
  74. return append(dst, s...)
  75. case 0:
  76. // denormalized
  77. exp++
  78. default:
  79. // add implicit top bit
  80. mant |= uint64(1) << flt.mantbits
  81. }
  82. exp += flt.bias
  83. // Pick off easy binary format.
  84. if fmt == 'b' {
  85. return fmtB(dst, neg, mant, exp, flt)
  86. }
  87. if !optimize {
  88. return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
  89. }
  90. var digs decimalSlice
  91. ok := false
  92. // Negative precision means "only as much as needed to be exact."
  93. shortest := prec < 0
  94. if shortest {
  95. // Try Grisu3 algorithm.
  96. f := new(extFloat)
  97. lower, upper := f.AssignComputeBounds(mant, exp, neg, flt)
  98. var buf [32]byte
  99. digs.d = buf[:]
  100. ok = f.ShortestDecimal(&digs, &lower, &upper)
  101. if !ok {
  102. return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
  103. }
  104. // Precision for shortest representation mode.
  105. switch fmt {
  106. case 'e', 'E':
  107. prec = digs.nd - 1
  108. case 'f':
  109. prec = max(digs.nd-digs.dp, 0)
  110. case 'g', 'G':
  111. prec = digs.nd
  112. }
  113. } else if fmt != 'f' {
  114. // Fixed number of digits.
  115. digits := prec
  116. switch fmt {
  117. case 'e', 'E':
  118. digits++
  119. case 'g', 'G':
  120. if prec == 0 {
  121. prec = 1
  122. }
  123. digits = prec
  124. }
  125. if digits <= 15 {
  126. // try fast algorithm when the number of digits is reasonable.
  127. var buf [24]byte
  128. digs.d = buf[:]
  129. f := extFloat{mant, exp - int(flt.mantbits), neg}
  130. ok = f.FixedDecimal(&digs, digits)
  131. }
  132. }
  133. if !ok {
  134. return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
  135. }
  136. return formatDigits(dst, shortest, neg, digs, prec, fmt)
  137. }
  138. // bigFtoa uses multiprecision computations to format a float.
  139. func bigFtoa(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
  140. d := new(decimal)
  141. d.Assign(mant)
  142. d.Shift(exp - int(flt.mantbits))
  143. var digs decimalSlice
  144. shortest := prec < 0
  145. if shortest {
  146. roundShortest(d, mant, exp, flt)
  147. digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
  148. // Precision for shortest representation mode.
  149. switch fmt {
  150. case 'e', 'E':
  151. prec = digs.nd - 1
  152. case 'f':
  153. prec = max(digs.nd-digs.dp, 0)
  154. case 'g', 'G':
  155. prec = digs.nd
  156. }
  157. } else {
  158. // Round appropriately.
  159. switch fmt {
  160. case 'e', 'E':
  161. d.Round(prec + 1)
  162. case 'f':
  163. d.Round(d.dp + prec)
  164. case 'g', 'G':
  165. if prec == 0 {
  166. prec = 1
  167. }
  168. d.Round(prec)
  169. }
  170. digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
  171. }
  172. return formatDigits(dst, shortest, neg, digs, prec, fmt)
  173. }
  174. func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) []byte {
  175. switch fmt {
  176. case 'e', 'E':
  177. return fmtE(dst, neg, digs, prec, fmt)
  178. case 'f':
  179. return fmtF(dst, neg, digs, prec)
  180. case 'g', 'G':
  181. // trailing fractional zeros in 'e' form will be trimmed.
  182. eprec := prec
  183. if eprec > digs.nd && digs.nd >= digs.dp {
  184. eprec = digs.nd
  185. }
  186. // %e is used if the exponent from the conversion
  187. // is less than -4 or greater than or equal to the precision.
  188. // if precision was the shortest possible, use precision 6 for this decision.
  189. if shortest {
  190. eprec = 6
  191. }
  192. exp := digs.dp - 1
  193. if exp < -4 || exp >= eprec {
  194. if prec > digs.nd {
  195. prec = digs.nd
  196. }
  197. return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
  198. }
  199. if prec > digs.dp {
  200. prec = digs.nd
  201. }
  202. return fmtF(dst, neg, digs, max(prec-digs.dp, 0))
  203. }
  204. // unknown format
  205. return append(dst, '%', fmt)
  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 []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
  305. // sign
  306. if neg {
  307. dst = append(dst, '-')
  308. }
  309. // first digit
  310. ch := byte('0')
  311. if d.nd != 0 {
  312. ch = d.d[0]
  313. }
  314. dst = append(dst, ch)
  315. // .moredigits
  316. if prec > 0 {
  317. dst = append(dst, '.')
  318. i := 1
  319. m := d.nd + prec + 1 - max(d.nd, prec+1)
  320. for i < m {
  321. dst = append(dst, d.d[i])
  322. i++
  323. }
  324. for i <= prec {
  325. dst = append(dst, '0')
  326. i++
  327. }
  328. }
  329. // e±
  330. dst = append(dst, 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 = append(dst, ch)
  342. // dddd
  343. var buf [3]byte
  344. i := len(buf)
  345. for exp >= 10 {
  346. i--
  347. buf[i] = byte(exp%10 + '0')
  348. exp /= 10
  349. }
  350. // exp < 10
  351. i--
  352. buf[i] = byte(exp + '0')
  353. switch i {
  354. case 0:
  355. dst = append(dst, buf[0], buf[1], buf[2])
  356. case 1:
  357. dst = append(dst, buf[1], buf[2])
  358. case 2:
  359. // leading zeroes
  360. dst = append(dst, '0', buf[2])
  361. }
  362. return dst
  363. }
  364. // %f: -ddddddd.ddddd
  365. func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
  366. // sign
  367. if neg {
  368. dst = append(dst, '-')
  369. }
  370. // integer, padded with zeros as needed.
  371. if d.dp > 0 {
  372. var i int
  373. for i = 0; i < d.dp && i < d.nd; i++ {
  374. dst = append(dst, d.d[i])
  375. }
  376. for ; i < d.dp; i++ {
  377. dst = append(dst, '0')
  378. }
  379. } else {
  380. dst = append(dst, '0')
  381. }
  382. // fraction
  383. if prec > 0 {
  384. dst = append(dst, '.')
  385. for i := 0; i < prec; i++ {
  386. ch := byte('0')
  387. if j := d.dp + i; 0 <= j && j < d.nd {
  388. ch = d.d[j]
  389. }
  390. dst = append(dst, ch)
  391. }
  392. }
  393. return dst
  394. }
  395. // %b: -ddddddddp+ddd
  396. func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
  397. var buf [50]byte
  398. w := len(buf)
  399. exp -= int(flt.mantbits)
  400. esign := byte('+')
  401. if exp < 0 {
  402. esign = '-'
  403. exp = -exp
  404. }
  405. n := 0
  406. for exp > 0 || n < 1 {
  407. n++
  408. w--
  409. buf[w] = byte(exp%10 + '0')
  410. exp /= 10
  411. }
  412. w--
  413. buf[w] = esign
  414. w--
  415. buf[w] = 'p'
  416. n = 0
  417. for mant > 0 || n < 1 {
  418. n++
  419. w--
  420. buf[w] = byte(mant%10 + '0')
  421. mant /= 10
  422. }
  423. if neg {
  424. w--
  425. buf[w] = '-'
  426. }
  427. return append(dst, buf[w:]...)
  428. }
  429. func max(a, b int) int {
  430. if a > b {
  431. return a
  432. }
  433. return b
  434. }