feature_iter_float.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package jsoniter
  2. import (
  3. "io"
  4. "strconv"
  5. "unsafe"
  6. )
  7. var floatDigits []int8
  8. const invalidCharForNumber = int8(-1)
  9. const endOfNumber = int8(-2)
  10. const dotInNumber = int8(-3)
  11. func init() {
  12. floatDigits = make([]int8, 256)
  13. for i := 0; i < len(floatDigits); i++ {
  14. floatDigits[i] = invalidCharForNumber
  15. }
  16. for i := int8('0'); i <= int8('9'); i++ {
  17. floatDigits[i] = i - int8('0')
  18. }
  19. floatDigits[','] = endOfNumber
  20. floatDigits[']'] = endOfNumber
  21. floatDigits['}'] = endOfNumber
  22. floatDigits[' '] = endOfNumber
  23. floatDigits['\t'] = endOfNumber
  24. floatDigits['\n'] = endOfNumber
  25. floatDigits['.'] = dotInNumber
  26. }
  27. func (iter *Iterator) ReadFloat32() (ret float32) {
  28. c := iter.nextToken()
  29. if c == '-' {
  30. return -iter.readPositiveFloat32()
  31. } else {
  32. iter.unreadByte()
  33. return iter.readPositiveFloat32()
  34. }
  35. }
  36. func (iter *Iterator) readPositiveFloat32() (ret float32) {
  37. value := uint64(0)
  38. c := byte(' ')
  39. i := iter.head
  40. non_decimal_loop:
  41. for ; i < iter.tail; i++ {
  42. c = iter.buf[i]
  43. ind := floatDigits[c]
  44. switch ind {
  45. case invalidCharForNumber:
  46. return iter.readFloat32SlowPath()
  47. case endOfNumber:
  48. iter.head = i
  49. return float32(value)
  50. case dotInNumber:
  51. break non_decimal_loop
  52. }
  53. if value > uint64SafeToMultiple10 {
  54. return iter.readFloat32SlowPath()
  55. }
  56. value = (value << 3) + (value << 1) + uint64(ind); // value = value * 10 + ind;
  57. }
  58. if c == '.' {
  59. i++
  60. decimalPlaces := 0;
  61. for ; i < iter.tail; i++ {
  62. c = iter.buf[i]
  63. ind := floatDigits[c];
  64. switch ind {
  65. case endOfNumber:
  66. if decimalPlaces > 0 && decimalPlaces < len(POW10) {
  67. iter.head = i
  68. return float32(float64(value) / float64(POW10[decimalPlaces]))
  69. }
  70. // too many decimal places
  71. return iter.readFloat32SlowPath()
  72. case invalidCharForNumber:
  73. fallthrough
  74. case dotInNumber:
  75. return iter.readFloat32SlowPath()
  76. }
  77. decimalPlaces++
  78. if value > uint64SafeToMultiple10 {
  79. return iter.readFloat32SlowPath()
  80. }
  81. value = (value << 3) + (value << 1) + uint64(ind)
  82. }
  83. }
  84. return iter.readFloat32SlowPath()
  85. }
  86. func (iter *Iterator) readFloat32SlowPath() (ret float32) {
  87. strBuf := [16]byte{}
  88. str := strBuf[0:0]
  89. load_loop:
  90. for {
  91. for i := iter.head; i < iter.tail; i++ {
  92. c := iter.buf[i]
  93. switch c {
  94. case '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  95. str = append(str, c)
  96. continue
  97. default:
  98. iter.head = i
  99. break load_loop
  100. }
  101. }
  102. if !iter.loadMore() {
  103. break
  104. }
  105. }
  106. if iter.Error != nil && iter.Error != io.EOF {
  107. return
  108. }
  109. val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 32)
  110. if err != nil {
  111. iter.Error = err
  112. return
  113. }
  114. return float32(val)
  115. }
  116. func (iter *Iterator) ReadFloat64() (ret float64) {
  117. c := iter.nextToken()
  118. if c == '-' {
  119. return -iter.readPositiveFloat64()
  120. } else {
  121. iter.unreadByte()
  122. return iter.readPositiveFloat64()
  123. }
  124. }
  125. func (iter *Iterator) readPositiveFloat64() (ret float64) {
  126. value := uint64(0)
  127. c := byte(' ')
  128. i := iter.head
  129. non_decimal_loop:
  130. for ; i < iter.tail; i++ {
  131. c = iter.buf[i]
  132. ind := floatDigits[c]
  133. switch ind {
  134. case invalidCharForNumber:
  135. return iter.readFloat64SlowPath()
  136. case endOfNumber:
  137. iter.head = i
  138. return float64(value)
  139. case dotInNumber:
  140. break non_decimal_loop
  141. }
  142. if value > uint64SafeToMultiple10 {
  143. return iter.readFloat64SlowPath()
  144. }
  145. value = (value << 3) + (value << 1) + uint64(ind); // value = value * 10 + ind;
  146. }
  147. if c == '.' {
  148. i++
  149. decimalPlaces := 0;
  150. for ; i < iter.tail; i++ {
  151. c = iter.buf[i]
  152. ind := floatDigits[c];
  153. switch ind {
  154. case endOfNumber:
  155. if decimalPlaces > 0 && decimalPlaces < len(POW10) {
  156. iter.head = i
  157. return float64(value) / float64(POW10[decimalPlaces])
  158. }
  159. // too many decimal places
  160. return iter.readFloat64SlowPath()
  161. case invalidCharForNumber:
  162. fallthrough
  163. case dotInNumber:
  164. return iter.readFloat64SlowPath()
  165. }
  166. decimalPlaces++
  167. if value > uint64SafeToMultiple10 {
  168. return iter.readFloat64SlowPath()
  169. }
  170. value = (value << 3) + (value << 1) + uint64(ind)
  171. }
  172. }
  173. return iter.readFloat64SlowPath()
  174. }
  175. func (iter *Iterator) readFloat64SlowPath() (ret float64) {
  176. strBuf := [16]byte{}
  177. str := strBuf[0:0]
  178. load_loop:
  179. for {
  180. for i := iter.head; i < iter.tail; i++ {
  181. c := iter.buf[i]
  182. switch c {
  183. case '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  184. str = append(str, c)
  185. continue
  186. default:
  187. iter.head = i
  188. break load_loop
  189. }
  190. }
  191. if !iter.loadMore() {
  192. break
  193. }
  194. }
  195. if iter.Error != nil && iter.Error != io.EOF {
  196. return
  197. }
  198. val, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&str)), 64)
  199. if err != nil {
  200. iter.Error = err
  201. return
  202. }
  203. return val
  204. }