common.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. Package ftoa provides ECMAScript-compliant floating point number conversion to string.
  3. It contains code ported from Rhino (https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/DToA.java)
  4. as well as from the original code by David M. Gay.
  5. See LICENSE_LUCENE for the original copyright message and disclaimer.
  6. */
  7. package ftoa
  8. import (
  9. "math"
  10. )
  11. const (
  12. frac_mask = 0xfffff
  13. exp_shift = 20
  14. exp_msk1 = 0x100000
  15. exp_shiftL = 52
  16. exp_mask_shifted = 0x7ff
  17. frac_maskL = 0xfffffffffffff
  18. exp_msk1L = 0x10000000000000
  19. exp_shift1 = 20
  20. exp_mask = 0x7ff00000
  21. bias = 1023
  22. p = 53
  23. bndry_mask = 0xfffff
  24. log2P = 1
  25. )
  26. func lo0bits(x uint32) (k int) {
  27. if (x & 7) != 0 {
  28. if (x & 1) != 0 {
  29. return 0
  30. }
  31. if (x & 2) != 0 {
  32. return 1
  33. }
  34. return 2
  35. }
  36. if (x & 0xffff) == 0 {
  37. k = 16
  38. x >>= 16
  39. }
  40. if (x & 0xff) == 0 {
  41. k += 8
  42. x >>= 8
  43. }
  44. if (x & 0xf) == 0 {
  45. k += 4
  46. x >>= 4
  47. }
  48. if (x & 0x3) == 0 {
  49. k += 2
  50. x >>= 2
  51. }
  52. if (x & 1) == 0 {
  53. k++
  54. x >>= 1
  55. if (x & 1) == 0 {
  56. return 32
  57. }
  58. }
  59. return
  60. }
  61. func hi0bits(x uint32) (k int) {
  62. if (x & 0xffff0000) == 0 {
  63. k = 16
  64. x <<= 16
  65. }
  66. if (x & 0xff000000) == 0 {
  67. k += 8
  68. x <<= 8
  69. }
  70. if (x & 0xf0000000) == 0 {
  71. k += 4
  72. x <<= 4
  73. }
  74. if (x & 0xc0000000) == 0 {
  75. k += 2
  76. x <<= 2
  77. }
  78. if (x & 0x80000000) == 0 {
  79. k++
  80. if (x & 0x40000000) == 0 {
  81. return 32
  82. }
  83. }
  84. return
  85. }
  86. func stuffBits(bits []byte, offset int, val uint32) {
  87. bits[offset] = byte(val >> 24)
  88. bits[offset+1] = byte(val >> 16)
  89. bits[offset+2] = byte(val >> 8)
  90. bits[offset+3] = byte(val)
  91. }
  92. func d2b(d float64, b []byte) (e, bits int, dblBits []byte) {
  93. dBits := math.Float64bits(d)
  94. d0 := uint32(dBits >> 32)
  95. d1 := uint32(dBits)
  96. z := d0 & frac_mask
  97. d0 &= 0x7fffffff /* clear sign bit, which we ignore */
  98. var de, k, i int
  99. if de = int(d0 >> exp_shift); de != 0 {
  100. z |= exp_msk1
  101. }
  102. y := d1
  103. if y != 0 {
  104. dblBits = b[:8]
  105. k = lo0bits(y)
  106. y >>= k
  107. if k != 0 {
  108. stuffBits(dblBits, 4, y|z<<(32-k))
  109. z >>= k
  110. } else {
  111. stuffBits(dblBits, 4, y)
  112. }
  113. stuffBits(dblBits, 0, z)
  114. if z != 0 {
  115. i = 2
  116. } else {
  117. i = 1
  118. }
  119. } else {
  120. dblBits = b[:4]
  121. k = lo0bits(z)
  122. z >>= k
  123. stuffBits(dblBits, 0, z)
  124. k += 32
  125. i = 1
  126. }
  127. if de != 0 {
  128. e = de - bias - (p - 1) + k
  129. bits = p - k
  130. } else {
  131. e = de - bias - (p - 1) + 1 + k
  132. bits = 32*i - hi0bits(z)
  133. }
  134. return
  135. }