feature_stream_float.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package jsoniter
  2. import (
  3. "strconv"
  4. "unsafe"
  5. )
  6. var POW10 []uint64
  7. func init() {
  8. POW10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000}
  9. }
  10. func (stream *Stream) WriteFloat32(val float32) {
  11. stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 32))
  12. }
  13. func (stream *Stream) WriteFloat32Lossy(val float32) {
  14. if val < 0 {
  15. stream.writeByte('-')
  16. val = -val
  17. }
  18. if val > 0x4ffffff {
  19. stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 32));
  20. return
  21. }
  22. precision := 6
  23. exp := uint64(1000000) // 6
  24. lval := uint64(float64(val) * float64(exp) + 0.5)
  25. stream.WriteUint64(lval / exp)
  26. fval := lval % exp
  27. if fval == 0 {
  28. return
  29. }
  30. stream.writeByte('.')
  31. if stream.Available() < 10 {
  32. stream.Flush()
  33. }
  34. for p := precision - 1; p > 0 && fval < POW10[p]; p-- {
  35. stream.writeByte('0')
  36. }
  37. stream.WriteUint64(fval)
  38. for stream.buf[stream.n - 1] == '0' {
  39. stream.n--
  40. }
  41. }
  42. func (stream *Stream) WriteFloat64(val float64) {
  43. stream.WriteRaw(strconv.FormatFloat(float64(val), 'f', -1, 64))
  44. }
  45. func (stream *Stream) WriteFloat64Lossy(val float64) {
  46. if val < 0 {
  47. stream.writeByte('-')
  48. val = -val
  49. }
  50. if val > 0x4ffffff {
  51. stream.WriteRaw(strconv.FormatFloat(val, 'f', -1, 64));
  52. return
  53. }
  54. precision := 6
  55. exp := uint64(1000000) // 6
  56. lval := uint64(val * float64(exp) + 0.5)
  57. stream.WriteUint64(lval / exp)
  58. fval := lval % exp
  59. if fval == 0 {
  60. return
  61. }
  62. stream.writeByte('.')
  63. if stream.Available() < 10 {
  64. stream.Flush()
  65. }
  66. for p := precision - 1; p > 0 && fval < POW10[p]; p-- {
  67. stream.writeByte('0')
  68. }
  69. stream.WriteUint64(fval)
  70. for stream.buf[stream.n - 1] == '0' {
  71. stream.n--
  72. }
  73. }
  74. func EnableLossyFloatMarshalling() {
  75. // for better performance
  76. RegisterTypeEncoder("float32", func(ptr unsafe.Pointer, stream *Stream) {
  77. val := *((*float32)(ptr))
  78. stream.WriteFloat32Lossy(val)
  79. })
  80. RegisterTypeEncoder("float64", func(ptr unsafe.Pointer, stream *Stream) {
  81. val := *((*float64)(ptr))
  82. stream.WriteFloat64Lossy(val)
  83. })
  84. }