UNPKG

1.22 kBJavaScriptView Raw
1'use strict'
2const bitwise = require('./bitwise')
3const bitNot = require('./bitNot')
4
5/**
6 * Bitwise XOR for BigNumbers
7 *
8 * Special Cases:
9 * N ^ n = N
10 * n ^ 0 = n
11 * n ^ n = 0
12 * n ^ -1 = ~n
13 * I ^ n = I
14 * I ^ -n = -I
15 * I ^ -I = -1
16 * -I ^ n = -I
17 * -I ^ -n = I
18 *
19 * @param {BigNumber} x
20 * @param {BigNumber} y
21 * @return {BigNumber} Result of `x` ^ `y`, fully precise
22 *
23 */
24module.exports = function bitXor (x, y) {
25 if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) {
26 throw new Error('Integers expected in function bitXor')
27 }
28
29 const BigNumber = x.constructor
30 if (x.isNaN() || y.isNaN()) {
31 return new BigNumber(NaN)
32 }
33 if (x.isZero()) {
34 return y
35 }
36 if (y.isZero()) {
37 return x
38 }
39
40 if (x.eq(y)) {
41 return new BigNumber(0)
42 }
43
44 const negOne = new BigNumber(-1)
45 if (x.eq(negOne)) {
46 return bitNot(y)
47 }
48 if (y.eq(negOne)) {
49 return bitNot(x)
50 }
51
52 if (!x.isFinite() || !y.isFinite()) {
53 if (!x.isFinite() && !y.isFinite()) {
54 return negOne
55 }
56 return new BigNumber(x.isNegative() === y.isNegative()
57 ? Infinity
58 : -Infinity)
59 }
60 return bitwise(x, y, function (a, b) { return a ^ b })
61}