JFIF  x x C         C     "        } !1AQa "q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz        w !1AQ aq"2B #3Rbr{ gilour
// @ts-check /** * We must remap all the old bits to new bits for each set variant * Only arbitrary variants are considered as those are the only * ones that need to be re-sorted at this time * * An iterated process that removes and sets individual bits simultaneously * will not work because we may have a new bit that is also a later old bit * This means that we would be removing a previously set bit which we don't * want to do * * For example (assume `bN` = `1<<N`) * Given the "total" mapping `[[b1, b3], [b2, b4], [b3, b1], [b4, b2]]` * The mapping is "total" because: * 1. Every input and output is accounted for * 2. All combinations are unique * 3. No one input maps to multiple outputs and vice versa * And, given an offset with all bits set: * V = b1 | b2 | b3 | b4 * * Let's explore the issue with removing and setting bits simultaneously: * V & ~b1 | b3 = b2 | b3 | b4 * V & ~b2 | b4 = b3 | b4 * V & ~b3 | b1 = b1 | b4 * V & ~b4 | b2 = b1 | b2 * * As you can see, we end up with the wrong result. * This is because we're removing a bit that was previously set. * And, thus the final result is missing b3 and b4. * * Now, let's explore the issue with removing the bits first: * V & ~b1 = b2 | b3 | b4 * V & ~b2 = b3 | b4 * V & ~b3 = b4 * V & ~b4 = 0 * * And then setting the bits: * V | b3 = b3 * V | b4 = b3 | b4 * V | b1 = b1 | b3 | b4 * V | b2 = b1 | b2 | b3 | b4 * * We get the correct result because we're not removing any bits that were * previously set thus properly remapping the bits to the new order * * To collect this into a single operation that can be done simultaneously * we must first create a mask for the old bits that are set and a mask for * the new bits that are set. Then we can remove the old bits and set the new * bits simultaneously in a "single" operation like so: * OldMask = b1 | b2 | b3 | b4 * NewMask = b3 | b4 | b1 | b2 * * So this: * V & ~oldMask | newMask * * Expands to this: * V & ~b1 & ~b2 & ~b3 & ~b4 | b3 | b4 | b1 | b2 * * Which becomes this: * b1 | b2 | b3 | b4 * * Which is the correct result! * * @param {bigint} num * @param {[bigint, bigint][]} mapping */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "remapBitfield", { enumerable: true, get: function() { return remapBitfield; } }); function remapBitfield(num, mapping) { // Create masks for the old and new bits that are set let oldMask = 0n; let newMask = 0n; for (let [oldBit, newBit] of mapping){ if (num & oldBit) { oldMask = oldMask | oldBit; newMask = newMask | newBit; } } // Remove all old bits // Set all new bits return num & ~oldMask | newMask; }