Double.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. import Long from './Long'
  2. export default function Double() { }
  3. Double.NaN = NaN
  4. Double.isNaN = n => Number.isNaN(n)
  5. Double.isInfinite = n => !Number.isFinite(n)
  6. Double.MAX_VALUE = Number.MAX_VALUE
  7. Double.POSITIVE_INFINITY = Number.POSITIVE_INFINITY
  8. Double.NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY
  9. if (typeof Float64Array === 'function' &&
  10. typeof Int32Array === 'function')
  11. // Simple and fast conversion between double and long bits
  12. // using TypedArrays and ArrayViewBuffers.
  13. (function() {
  14. const EXP_BIT_MASK = 0x7ff00000
  15. const SIGNIF_BIT_MASK = 0xFFFFF
  16. const f64buf = new Float64Array(1)
  17. const i32buf = new Int32Array(f64buf.buffer)
  18. Double.doubleToLongBits = function(value) {
  19. f64buf[0] = value
  20. let low = i32buf[0] | 0
  21. let high = i32buf[1] | 0
  22. // Check for NaN based on values of bit fields, maximum
  23. // exponent and nonzero significand.
  24. if (((high & EXP_BIT_MASK) === EXP_BIT_MASK) &&
  25. ((high & SIGNIF_BIT_MASK) !== 0) &&
  26. (low !== 0)) {
  27. low = 0 | 0
  28. high = 0x7ff80000 | 0
  29. }
  30. return new Long(high, low)
  31. }
  32. Double.longBitsToDouble = function(bits) {
  33. i32buf[0] = bits.low
  34. i32buf[1] = bits.high
  35. return f64buf[0]
  36. }
  37. })()
  38. else
  39. // More complex and slower fallback implementation using
  40. // math and the divide-by-two and multiply-by-two algorithms.
  41. (function() {
  42. const BIAS = 1023
  43. const log2 = Math.log2
  44. const floor = Math.floor
  45. const pow = Math.pow
  46. const MAX_REL_BITS_INTEGER = (function() {
  47. for (let i = 53; i > 0; i--) {
  48. const bits = pow(2, i) - 1
  49. if (floor(log2(bits)) + 1 === i) return bits
  50. }
  51. return 0
  52. })()
  53. Double.doubleToLongBits = function(value) {
  54. let x, y, f, bits, skip
  55. let sign, exp, high, low
  56. // Get the sign bit and absolute value.
  57. if (value < 0 || 1 / value === Number.NEGATIVE_INFINITY) {
  58. sign = (1 << 31)
  59. value = (-value)
  60. } else {
  61. sign = 0
  62. }
  63. // Handle some special values.
  64. if (value === 0) {
  65. // Handle zeros (+/-0).
  66. low = 0 | 0
  67. high = sign // exponent: 00..00, significand: 00..00
  68. return new Long(high, low)
  69. }
  70. if (value === Infinity) {
  71. // Handle infinity (only positive values for value possible).
  72. low = 0 | 0
  73. high = sign | 0x7ff00000 // exponent: 11..11, significand: 00..00
  74. return new Long(high, low)
  75. }
  76. if (value !== value) { // eslint-disable-line
  77. // Handle NaNs (boiled down to only one distinct NaN).
  78. low = 0 | 0
  79. high = 0x7ff80000 // exponent: 11..11, significand: 10..00
  80. return new Long(high, low)
  81. }
  82. // Preinitialize variables, that are not neccessarily set by
  83. // the algorithm.
  84. bits = 0
  85. low = 0 | 0
  86. // Get the (always positive) integer part of value.
  87. x = floor(value)
  88. // Process the integer part if it's greater than 1. Zero requires
  89. // no bits at all, 1 represents the implicit (hidden) leading bit,
  90. // which must not be written as well.
  91. if (x > 1)
  92. // If we can reliably determine the number of bits required for
  93. // the integer part,
  94. if (x <= MAX_REL_BITS_INTEGER) {
  95. // get the number of bits required to represent it minus 1
  96. bits = floor(log2(x)) /* + 1 - 1 */
  97. // and simply copy/shift the integer bits into low and high.
  98. // That's much faster than the divide-by-two algorithm (saves
  99. // up to ~60%).
  100. // We always need to mask out the most significant bit, which
  101. // is the implicit (aka hidden) bit.
  102. if (bits <= 20) {
  103. // The simple case in which the integer fits into the
  104. // lower 20 bits of the high word is worth to be handled
  105. // separately (saves ~25%).
  106. low = 0 | 0
  107. high = (x << (20 - bits)) & 0xfffff
  108. } else {
  109. // Here, the integer part is split into low and high.
  110. // Since its value may require more than 32 bits, we
  111. // cannot use bitwise operators (which implicitly cast
  112. // to Int32), but use arithmetic operators % and / to
  113. // get low and high parts. The uppper 20 bits go to high,
  114. // the remaining bits (in f) to low.
  115. f = bits - 20
  116. // Like (1 << f) but safe with even more than 32 bits.
  117. y = pow(2, f)
  118. low = (x % y) << (32 - f)
  119. high = (x / y) & 0xfffff
  120. }
  121. } else {
  122. // For greater values, we must use the much slower divide-by-two
  123. // algorithm. Bits are generated from right to left, that is from
  124. // least to most significant bit. For each bit, we left-shift both
  125. // low and high by one and carry bit #0 from high to #31 in low.
  126. // The next bit is then copied into bit #19 in high, the leftmost
  127. // bit of the double's significand.
  128. // Preserve x for later user, so work with f.
  129. f = x
  130. low = 0 | 0
  131. for (;;) {
  132. y = f / 2
  133. f = floor(y)
  134. if (f === 0)
  135. // We just found the most signigicant (1-)bit, which
  136. // is the implicit bit and so, not stored in the double
  137. // value. So, it's time to leave the loop.
  138. break
  139. // Count this bit, shift low and carry bit #0 from high.
  140. bits++
  141. low >>>= 1
  142. low |= (high & 0x1) << 31
  143. // Shift high.
  144. high >>>= 1
  145. if (y !== f)
  146. // Copy the new bit into bit #19 in high (only required if 1).
  147. high |= 0x80000
  148. }
  149. }
  150. // Bias the exponent.
  151. exp = bits + BIAS
  152. // If the integer part is zero, we've not yet seen the implicit
  153. // leading bit. Variable skip is later used while processing the
  154. // fractional part (if any).
  155. skip = (x === 0)
  156. // Get fraction only into x.
  157. x = value - x
  158. // If some significand bits are still left to be filled and
  159. // the fractional part is not zero, convert the fraction using
  160. // the multiply-by-2 algorithm.
  161. if (bits < 52 && x !== 0) {
  162. // Initialize 'buffer' f, into which newly created bits get
  163. // shifted from right to left.
  164. f = 0
  165. for (;;) {
  166. y = x * 2
  167. if (y >= 1) {
  168. // This is a new 1-bit. Add and count this bit, if not
  169. // prohibited by skip.
  170. x = y - 1
  171. if (!skip) {
  172. f <<= 1
  173. f |= 1
  174. bits++
  175. } else {
  176. // Otherwise, decrement the exponent and unset
  177. // skip, so that all following bits get written.
  178. exp--
  179. skip = false
  180. }
  181. } else {
  182. // This is a new 0-bit. Add and count this bit, if not
  183. // prohibited by skip.
  184. x = y
  185. if (!skip) {
  186. f <<= 1
  187. bits++
  188. } else if (--exp === 0) {
  189. // Otherwise we've just decremented the exponent. If the
  190. // biased exponent is zero now (-1023), we process a
  191. // subnormal number, which has no impled leading 1-bit.
  192. // So, count this 0-bit and unset skip to write out
  193. // all the following bits.
  194. bits++
  195. skip = false
  196. }
  197. }
  198. if (bits === 20) {
  199. // When 20 bits have been created in total, we're done with
  200. // the high word. Copy the bits from 'buffer' f into high
  201. // and reset 'buffer' f. Following bits will end up in the
  202. // low word.
  203. high |= f
  204. f = 0
  205. } else if (bits === 52) {
  206. // When 52 bits have been created in total, we're done with
  207. // low word as well. Copy the bits from 'buffer' f into low
  208. // and exit the loop.
  209. low |= f
  210. break
  211. }
  212. if (y === 1) {
  213. // When y is exactly 1, there is no remainder and the process
  214. // is complete (the number is finite). Copy the bits from
  215. // 'buffer' f into either low or high and exit the loop.
  216. if (bits < 20)
  217. high |= (f << (20 - bits))
  218. else if (bits < 52) low |= (f << (52 - bits))
  219. break
  220. }
  221. }
  222. }
  223. // Copy/shift the exponent and sign bits into the high word.
  224. high |= (exp << 20)
  225. high |= sign
  226. return new Long(high, low)
  227. }
  228. Double.longBitsToDouble = function(bits) {
  229. let i
  230. let x, exp, fract
  231. const high = bits.high
  232. const low = bits.low
  233. // Extract the sign.
  234. const sign = (high & (1 << 31)) ? -1 : 1
  235. // Extract the unbiased exponent.
  236. exp = ((high & 0x7ff00000) >> 20) - BIAS
  237. // Calculate the fraction from left to right. Start
  238. // off with the 20 lower bits from the high word.
  239. fract = 0
  240. x = (1 << 19)
  241. for (i = 1; i <= 20; i++) {
  242. if (high & x) fract += pow(2, -i)
  243. x >>>= 1
  244. }
  245. // Continue with all 32 bits from the low word.
  246. x = (1 << 31)
  247. for (i = 21; i <= 52; i++) {
  248. if (low & x) fract += pow(2, -i)
  249. x >>>= 1
  250. }
  251. // Handle special values.
  252. // Check for zero and subnormal values.
  253. if (exp === -BIAS) {
  254. if (fract === 0)
  255. // +/-1.0 * 0.0 => +/-0.0
  256. return sign * 0
  257. exp = -1022
  258. } else if (exp === BIAS + 1) { // Check for +/-Infinity or NaN.
  259. if (fract === 0)
  260. // +/-1.0 / 0.0 => +/-Infinity
  261. return sign / 0
  262. return NaN
  263. } else { // Nothing special? Seems to be a normal number.
  264. // Add the implicit leading bit (1*2^0).
  265. fract += 1
  266. }
  267. return sign * fract * pow(2, exp)
  268. }
  269. })()