uint64.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /**
  2. C-like unsigned 64 bits integers in Javascript
  3. Copyright (C) 2013, Pierre Curto
  4. MIT license
  5. */
  6. ;(function (root) {
  7. // Local cache for typical radices
  8. var radixPowerCache = {
  9. 16: UINT64( Math.pow(16, 5) )
  10. , 10: UINT64( Math.pow(10, 5) )
  11. , 2: UINT64( Math.pow(2, 5) )
  12. }
  13. var radixCache = {
  14. 16: UINT64(16)
  15. , 10: UINT64(10)
  16. , 2: UINT64(2)
  17. }
  18. /**
  19. * Represents an unsigned 64 bits integer
  20. * @constructor
  21. * @param {Number} first low bits (8)
  22. * @param {Number} second low bits (8)
  23. * @param {Number} first high bits (8)
  24. * @param {Number} second high bits (8)
  25. * or
  26. * @param {Number} low bits (32)
  27. * @param {Number} high bits (32)
  28. * or
  29. * @param {String|Number} integer as a string | integer as a number
  30. * @param {Number|Undefined} radix (optional, default=10)
  31. * @return
  32. */
  33. function UINT64 (a00, a16, a32, a48) {
  34. if ( !(this instanceof UINT64) )
  35. return new UINT64(a00, a16, a32, a48)
  36. this.remainder = null
  37. if (typeof a00 == 'string')
  38. return fromString.call(this, a00, a16)
  39. if (typeof a16 == 'undefined')
  40. return fromNumber.call(this, a00)
  41. fromBits.apply(this, arguments)
  42. }
  43. /**
  44. * Set the current _UINT64_ object with its low and high bits
  45. * @method fromBits
  46. * @param {Number} first low bits (8)
  47. * @param {Number} second low bits (8)
  48. * @param {Number} first high bits (8)
  49. * @param {Number} second high bits (8)
  50. * or
  51. * @param {Number} low bits (32)
  52. * @param {Number} high bits (32)
  53. * @return ThisExpression
  54. */
  55. function fromBits (a00, a16, a32, a48) {
  56. if (typeof a32 == 'undefined') {
  57. this._a00 = a00 & 0xFFFF
  58. this._a16 = a00 >>> 16
  59. this._a32 = a16 & 0xFFFF
  60. this._a48 = a16 >>> 16
  61. return this
  62. }
  63. this._a00 = a00 | 0
  64. this._a16 = a16 | 0
  65. this._a32 = a32 | 0
  66. this._a48 = a48 | 0
  67. return this
  68. }
  69. UINT64.prototype.fromBits = fromBits
  70. /**
  71. * Set the current _UINT64_ object from a number
  72. * @method fromNumber
  73. * @param {Number} number
  74. * @return ThisExpression
  75. */
  76. function fromNumber (value) {
  77. this._a00 = value & 0xFFFF
  78. this._a16 = value >>> 16
  79. this._a32 = 0
  80. this._a48 = 0
  81. return this
  82. }
  83. UINT64.prototype.fromNumber = fromNumber
  84. /**
  85. * Set the current _UINT64_ object from a string
  86. * @method fromString
  87. * @param {String} integer as a string
  88. * @param {Number} radix (optional, default=10)
  89. * @return ThisExpression
  90. */
  91. function fromString (s, radix) {
  92. radix = radix || 10
  93. this._a00 = 0
  94. this._a16 = 0
  95. this._a32 = 0
  96. this._a48 = 0
  97. /*
  98. In Javascript, bitwise operators only operate on the first 32 bits
  99. of a number, even though parseInt() encodes numbers with a 53 bits
  100. mantissa.
  101. Therefore UINT64(<Number>) can only work on 32 bits.
  102. The radix maximum value is 36 (as per ECMA specs) (26 letters + 10 digits)
  103. maximum input value is m = 32bits as 1 = 2^32 - 1
  104. So the maximum substring length n is:
  105. 36^(n+1) - 1 = 2^32 - 1
  106. 36^(n+1) = 2^32
  107. (n+1)ln(36) = 32ln(2)
  108. n = 32ln(2)/ln(36) - 1
  109. n = 5.189644915687692
  110. n = 5
  111. */
  112. var radixUint = radixPowerCache[radix] || new UINT64( Math.pow(radix, 5) )
  113. for (var i = 0, len = s.length; i < len; i += 5) {
  114. var size = Math.min(5, len - i)
  115. var value = parseInt( s.slice(i, i + size), radix )
  116. this.multiply(
  117. size < 5
  118. ? new UINT64( Math.pow(radix, size) )
  119. : radixUint
  120. )
  121. .add( new UINT64(value) )
  122. }
  123. return this
  124. }
  125. UINT64.prototype.fromString = fromString
  126. /**
  127. * Convert this _UINT64_ to a number (last 32 bits are dropped)
  128. * @method toNumber
  129. * @return {Number} the converted UINT64
  130. */
  131. UINT64.prototype.toNumber = function () {
  132. return (this._a16 * 65536) + this._a00
  133. }
  134. /**
  135. * Convert this _UINT64_ to a string
  136. * @method toString
  137. * @param {Number} radix (optional, default=10)
  138. * @return {String} the converted UINT64
  139. */
  140. UINT64.prototype.toString = function (radix) {
  141. radix = radix || 10
  142. var radixUint = radixCache[radix] || new UINT64(radix)
  143. if ( !this.gt(radixUint) ) return this.toNumber().toString(radix)
  144. var self = this.clone()
  145. var res = new Array(64)
  146. for (var i = 63; i >= 0; i--) {
  147. self.div(radixUint)
  148. res[i] = self.remainder.toNumber().toString(radix)
  149. if ( !self.gt(radixUint) ) break
  150. }
  151. res[i-1] = self.toNumber().toString(radix)
  152. return res.join('')
  153. }
  154. /**
  155. * Add two _UINT64_. The current _UINT64_ stores the result
  156. * @method add
  157. * @param {Object} other UINT64
  158. * @return ThisExpression
  159. */
  160. UINT64.prototype.add = function (other) {
  161. var a00 = this._a00 + other._a00
  162. var a16 = a00 >>> 16
  163. a16 += this._a16 + other._a16
  164. var a32 = a16 >>> 16
  165. a32 += this._a32 + other._a32
  166. var a48 = a32 >>> 16
  167. a48 += this._a48 + other._a48
  168. this._a00 = a00 & 0xFFFF
  169. this._a16 = a16 & 0xFFFF
  170. this._a32 = a32 & 0xFFFF
  171. this._a48 = a48 & 0xFFFF
  172. return this
  173. }
  174. /**
  175. * Subtract two _UINT64_. The current _UINT64_ stores the result
  176. * @method subtract
  177. * @param {Object} other UINT64
  178. * @return ThisExpression
  179. */
  180. UINT64.prototype.subtract = function (other) {
  181. return this.add( other.clone().negate() )
  182. }
  183. /**
  184. * Multiply two _UINT64_. The current _UINT64_ stores the result
  185. * @method multiply
  186. * @param {Object} other UINT64
  187. * @return ThisExpression
  188. */
  189. UINT64.prototype.multiply = function (other) {
  190. /*
  191. a = a00 + a16 + a32 + a48
  192. b = b00 + b16 + b32 + b48
  193. a*b = (a00 + a16 + a32 + a48)(b00 + b16 + b32 + b48)
  194. = a00b00 + a00b16 + a00b32 + a00b48
  195. + a16b00 + a16b16 + a16b32 + a16b48
  196. + a32b00 + a32b16 + a32b32 + a32b48
  197. + a48b00 + a48b16 + a48b32 + a48b48
  198. a16b48, a32b32, a48b16, a48b32 and a48b48 overflow the 64 bits
  199. so it comes down to:
  200. a*b = a00b00 + a00b16 + a00b32 + a00b48
  201. + a16b00 + a16b16 + a16b32
  202. + a32b00 + a32b16
  203. + a48b00
  204. = a00b00
  205. + a00b16 + a16b00
  206. + a00b32 + a16b16 + a32b00
  207. + a00b48 + a16b32 + a32b16 + a48b00
  208. */
  209. var a00 = this._a00
  210. var a16 = this._a16
  211. var a32 = this._a32
  212. var a48 = this._a48
  213. var b00 = other._a00
  214. var b16 = other._a16
  215. var b32 = other._a32
  216. var b48 = other._a48
  217. var c00 = a00 * b00
  218. var c16 = c00 >>> 16
  219. c16 += a00 * b16
  220. var c32 = c16 >>> 16
  221. c16 &= 0xFFFF
  222. c16 += a16 * b00
  223. c32 += c16 >>> 16
  224. c32 += a00 * b32
  225. var c48 = c32 >>> 16
  226. c32 &= 0xFFFF
  227. c32 += a16 * b16
  228. c48 += c32 >>> 16
  229. c32 &= 0xFFFF
  230. c32 += a32 * b00
  231. c48 += c32 >>> 16
  232. c48 += a00 * b48
  233. c48 &= 0xFFFF
  234. c48 += a16 * b32
  235. c48 &= 0xFFFF
  236. c48 += a32 * b16
  237. c48 &= 0xFFFF
  238. c48 += a48 * b00
  239. this._a00 = c00 & 0xFFFF
  240. this._a16 = c16 & 0xFFFF
  241. this._a32 = c32 & 0xFFFF
  242. this._a48 = c48 & 0xFFFF
  243. return this
  244. }
  245. /**
  246. * Divide two _UINT64_. The current _UINT64_ stores the result.
  247. * The remainder is made available as the _remainder_ property on
  248. * the _UINT64_ object. It can be null, meaning there are no remainder.
  249. * @method div
  250. * @param {Object} other UINT64
  251. * @return ThisExpression
  252. */
  253. UINT64.prototype.div = function (other) {
  254. if ( (other._a16 == 0) && (other._a32 == 0) && (other._a48 == 0) ) {
  255. if (other._a00 == 0) throw Error('division by zero')
  256. // other == 1: this
  257. if (other._a00 == 1) {
  258. this.remainder = new UINT64(0)
  259. return this
  260. }
  261. }
  262. // other > this: 0
  263. if ( other.gt(this) ) {
  264. this.remainder = this.clone()
  265. this._a00 = 0
  266. this._a16 = 0
  267. this._a32 = 0
  268. this._a48 = 0
  269. return this
  270. }
  271. // other == this: 1
  272. if ( this.eq(other) ) {
  273. this.remainder = new UINT64(0)
  274. this._a00 = 1
  275. this._a16 = 0
  276. this._a32 = 0
  277. this._a48 = 0
  278. return this
  279. }
  280. // Shift the divisor left until it is higher than the dividend
  281. var _other = other.clone()
  282. var i = -1
  283. while ( !this.lt(_other) ) {
  284. // High bit can overflow the default 16bits
  285. // Its ok since we right shift after this loop
  286. // The overflown bit must be kept though
  287. _other.shiftLeft(1, true)
  288. i++
  289. }
  290. // Set the remainder
  291. this.remainder = this.clone()
  292. // Initialize the current result to 0
  293. this._a00 = 0
  294. this._a16 = 0
  295. this._a32 = 0
  296. this._a48 = 0
  297. for (; i >= 0; i--) {
  298. _other.shiftRight(1)
  299. // If shifted divisor is smaller than the dividend
  300. // then subtract it from the dividend
  301. if ( !this.remainder.lt(_other) ) {
  302. this.remainder.subtract(_other)
  303. // Update the current result
  304. if (i >= 48) {
  305. this._a48 |= 1 << (i - 48)
  306. } else if (i >= 32) {
  307. this._a32 |= 1 << (i - 32)
  308. } else if (i >= 16) {
  309. this._a16 |= 1 << (i - 16)
  310. } else {
  311. this._a00 |= 1 << i
  312. }
  313. }
  314. }
  315. return this
  316. }
  317. /**
  318. * Negate the current _UINT64_
  319. * @method negate
  320. * @return ThisExpression
  321. */
  322. UINT64.prototype.negate = function () {
  323. var v = ( ~this._a00 & 0xFFFF ) + 1
  324. this._a00 = v & 0xFFFF
  325. v = (~this._a16 & 0xFFFF) + (v >>> 16)
  326. this._a16 = v & 0xFFFF
  327. v = (~this._a32 & 0xFFFF) + (v >>> 16)
  328. this._a32 = v & 0xFFFF
  329. this._a48 = (~this._a48 + (v >>> 16)) & 0xFFFF
  330. return this
  331. }
  332. /**
  333. * @method eq
  334. * @param {Object} other UINT64
  335. * @return {Boolean}
  336. */
  337. UINT64.prototype.equals = UINT64.prototype.eq = function (other) {
  338. return (this._a48 == other._a48) && (this._a00 == other._a00)
  339. && (this._a32 == other._a32) && (this._a16 == other._a16)
  340. }
  341. /**
  342. * Greater than (strict)
  343. * @method gt
  344. * @param {Object} other UINT64
  345. * @return {Boolean}
  346. */
  347. UINT64.prototype.greaterThan = UINT64.prototype.gt = function (other) {
  348. if (this._a48 > other._a48) return true
  349. if (this._a48 < other._a48) return false
  350. if (this._a32 > other._a32) return true
  351. if (this._a32 < other._a32) return false
  352. if (this._a16 > other._a16) return true
  353. if (this._a16 < other._a16) return false
  354. return this._a00 > other._a00
  355. }
  356. /**
  357. * Less than (strict)
  358. * @method lt
  359. * @param {Object} other UINT64
  360. * @return {Boolean}
  361. */
  362. UINT64.prototype.lessThan = UINT64.prototype.lt = function (other) {
  363. if (this._a48 < other._a48) return true
  364. if (this._a48 > other._a48) return false
  365. if (this._a32 < other._a32) return true
  366. if (this._a32 > other._a32) return false
  367. if (this._a16 < other._a16) return true
  368. if (this._a16 > other._a16) return false
  369. return this._a00 < other._a00
  370. }
  371. /**
  372. * Bitwise OR
  373. * @method or
  374. * @param {Object} other UINT64
  375. * @return ThisExpression
  376. */
  377. UINT64.prototype.or = function (other) {
  378. this._a00 |= other._a00
  379. this._a16 |= other._a16
  380. this._a32 |= other._a32
  381. this._a48 |= other._a48
  382. return this
  383. }
  384. /**
  385. * Bitwise AND
  386. * @method and
  387. * @param {Object} other UINT64
  388. * @return ThisExpression
  389. */
  390. UINT64.prototype.and = function (other) {
  391. this._a00 &= other._a00
  392. this._a16 &= other._a16
  393. this._a32 &= other._a32
  394. this._a48 &= other._a48
  395. return this
  396. }
  397. /**
  398. * Bitwise XOR
  399. * @method xor
  400. * @param {Object} other UINT64
  401. * @return ThisExpression
  402. */
  403. UINT64.prototype.xor = function (other) {
  404. this._a00 ^= other._a00
  405. this._a16 ^= other._a16
  406. this._a32 ^= other._a32
  407. this._a48 ^= other._a48
  408. return this
  409. }
  410. /**
  411. * Bitwise NOT
  412. * @method not
  413. * @return ThisExpression
  414. */
  415. UINT64.prototype.not = function() {
  416. this._a00 = ~this._a00 & 0xFFFF
  417. this._a16 = ~this._a16 & 0xFFFF
  418. this._a32 = ~this._a32 & 0xFFFF
  419. this._a48 = ~this._a48 & 0xFFFF
  420. return this
  421. }
  422. /**
  423. * Bitwise shift right
  424. * @method shiftRight
  425. * @param {Number} number of bits to shift
  426. * @return ThisExpression
  427. */
  428. UINT64.prototype.shiftRight = UINT64.prototype.shiftr = function (n) {
  429. n %= 64
  430. if (n >= 48) {
  431. this._a00 = this._a48 >> (n - 48)
  432. this._a16 = 0
  433. this._a32 = 0
  434. this._a48 = 0
  435. } else if (n >= 32) {
  436. n -= 32
  437. this._a00 = ( (this._a32 >> n) | (this._a48 << (16-n)) ) & 0xFFFF
  438. this._a16 = (this._a48 >> n) & 0xFFFF
  439. this._a32 = 0
  440. this._a48 = 0
  441. } else if (n >= 16) {
  442. n -= 16
  443. this._a00 = ( (this._a16 >> n) | (this._a32 << (16-n)) ) & 0xFFFF
  444. this._a16 = ( (this._a32 >> n) | (this._a48 << (16-n)) ) & 0xFFFF
  445. this._a32 = (this._a48 >> n) & 0xFFFF
  446. this._a48 = 0
  447. } else {
  448. this._a00 = ( (this._a00 >> n) | (this._a16 << (16-n)) ) & 0xFFFF
  449. this._a16 = ( (this._a16 >> n) | (this._a32 << (16-n)) ) & 0xFFFF
  450. this._a32 = ( (this._a32 >> n) | (this._a48 << (16-n)) ) & 0xFFFF
  451. this._a48 = (this._a48 >> n) & 0xFFFF
  452. }
  453. return this
  454. }
  455. /**
  456. * Bitwise shift left
  457. * @method shiftLeft
  458. * @param {Number} number of bits to shift
  459. * @param {Boolean} allow overflow
  460. * @return ThisExpression
  461. */
  462. UINT64.prototype.shiftLeft = UINT64.prototype.shiftl = function (n, allowOverflow) {
  463. n %= 64
  464. if (n >= 48) {
  465. this._a48 = this._a00 << (n - 48)
  466. this._a32 = 0
  467. this._a16 = 0
  468. this._a00 = 0
  469. } else if (n >= 32) {
  470. n -= 32
  471. this._a48 = (this._a16 << n) | (this._a00 >> (16-n))
  472. this._a32 = (this._a00 << n) & 0xFFFF
  473. this._a16 = 0
  474. this._a00 = 0
  475. } else if (n >= 16) {
  476. n -= 16
  477. this._a48 = (this._a32 << n) | (this._a16 >> (16-n))
  478. this._a32 = ( (this._a16 << n) | (this._a00 >> (16-n)) ) & 0xFFFF
  479. this._a16 = (this._a00 << n) & 0xFFFF
  480. this._a00 = 0
  481. } else {
  482. this._a48 = (this._a48 << n) | (this._a32 >> (16-n))
  483. this._a32 = ( (this._a32 << n) | (this._a16 >> (16-n)) ) & 0xFFFF
  484. this._a16 = ( (this._a16 << n) | (this._a00 >> (16-n)) ) & 0xFFFF
  485. this._a00 = (this._a00 << n) & 0xFFFF
  486. }
  487. if (!allowOverflow) {
  488. this._a48 &= 0xFFFF
  489. }
  490. return this
  491. }
  492. /**
  493. * Bitwise rotate left
  494. * @method rotl
  495. * @param {Number} number of bits to rotate
  496. * @return ThisExpression
  497. */
  498. UINT64.prototype.rotateLeft = UINT64.prototype.rotl = function (n) {
  499. n %= 64
  500. if (n == 0) return this
  501. if (n >= 32) {
  502. // A.B.C.D
  503. // B.C.D.A rotl(16)
  504. // C.D.A.B rotl(32)
  505. var v = this._a00
  506. this._a00 = this._a32
  507. this._a32 = v
  508. v = this._a48
  509. this._a48 = this._a16
  510. this._a16 = v
  511. if (n == 32) return this
  512. n -= 32
  513. }
  514. var high = (this._a48 << 16) | this._a32
  515. var low = (this._a16 << 16) | this._a00
  516. var _high = (high << n) | (low >>> (32 - n))
  517. var _low = (low << n) | (high >>> (32 - n))
  518. this._a00 = _low & 0xFFFF
  519. this._a16 = _low >>> 16
  520. this._a32 = _high & 0xFFFF
  521. this._a48 = _high >>> 16
  522. return this
  523. }
  524. /**
  525. * Bitwise rotate right
  526. * @method rotr
  527. * @param {Number} number of bits to rotate
  528. * @return ThisExpression
  529. */
  530. UINT64.prototype.rotateRight = UINT64.prototype.rotr = function (n) {
  531. n %= 64
  532. if (n == 0) return this
  533. if (n >= 32) {
  534. // A.B.C.D
  535. // D.A.B.C rotr(16)
  536. // C.D.A.B rotr(32)
  537. var v = this._a00
  538. this._a00 = this._a32
  539. this._a32 = v
  540. v = this._a48
  541. this._a48 = this._a16
  542. this._a16 = v
  543. if (n == 32) return this
  544. n -= 32
  545. }
  546. var high = (this._a48 << 16) | this._a32
  547. var low = (this._a16 << 16) | this._a00
  548. var _high = (high >>> n) | (low << (32 - n))
  549. var _low = (low >>> n) | (high << (32 - n))
  550. this._a00 = _low & 0xFFFF
  551. this._a16 = _low >>> 16
  552. this._a32 = _high & 0xFFFF
  553. this._a48 = _high >>> 16
  554. return this
  555. }
  556. /**
  557. * Clone the current _UINT64_
  558. * @method clone
  559. * @return {Object} cloned UINT64
  560. */
  561. UINT64.prototype.clone = function () {
  562. return new UINT64(this._a00, this._a16, this._a32, this._a48)
  563. }
  564. if (typeof define != 'undefined' && define.amd) {
  565. // AMD / RequireJS
  566. define([], function () {
  567. return UINT64
  568. })
  569. } else if (typeof module != 'undefined' && module.exports) {
  570. // Node.js
  571. module.exports = UINT64
  572. } else {
  573. // Browser
  574. root['UINT64'] = UINT64
  575. }
  576. })(this)