You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					110 lines
				
				2.2 KiB
			
		
		
			
		
	
	
					110 lines
				
				2.2 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Mnemonist Bitwise Helpers
							 | 
						||
| 
								 | 
							
								 * ==========================
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Miscellaneous helpers helping with bitwise operations.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Takes a 32 bits integer and returns its MSB using SWAR strategy.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {number} x - Target number.
							 | 
						||
| 
								 | 
							
								 * @return {number}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function msb32(x) {
							 | 
						||
| 
								 | 
							
								  x |= (x >> 1);
							 | 
						||
| 
								 | 
							
								  x |= (x >> 2);
							 | 
						||
| 
								 | 
							
								  x |= (x >> 4);
							 | 
						||
| 
								 | 
							
								  x |= (x >> 8);
							 | 
						||
| 
								 | 
							
								  x |= (x >> 16);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return (x & ~(x >> 1));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								exports.msb32 = msb32;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Takes a byte and returns its MSB using SWAR strategy.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {number} x - Target number.
							 | 
						||
| 
								 | 
							
								 * @return {number}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function msb8(x) {
							 | 
						||
| 
								 | 
							
								  x |= (x >> 1);
							 | 
						||
| 
								 | 
							
								  x |= (x >> 2);
							 | 
						||
| 
								 | 
							
								  x |= (x >> 4);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return (x & ~(x >> 1));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								exports.msb8 = msb8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Takes a number and return bit at position.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {number} x   - Target number.
							 | 
						||
| 
								 | 
							
								 * @param  {number} pos - Position.
							 | 
						||
| 
								 | 
							
								 * @return {number}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								exports.test = function(x, pos) {
							 | 
						||
| 
								 | 
							
								  return (x >> pos) & 1;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Compare two bytes and return their critical bit.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {number} a - First byte.
							 | 
						||
| 
								 | 
							
								 * @param  {number} b - Second byte.
							 | 
						||
| 
								 | 
							
								 * @return {number}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								exports.criticalBit8 = function(a, b) {
							 | 
						||
| 
								 | 
							
								  return msb8(a ^ b);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.criticalBit8Mask = function(a, b) {
							 | 
						||
| 
								 | 
							
								  return (~msb8(a ^ b) >>> 0) & 0xff;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.testCriticalBit8 = function(x, mask) {
							 | 
						||
| 
								 | 
							
								  return (1 + (x | mask)) >> 8;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.criticalBit32Mask = function(a, b) {
							 | 
						||
| 
								 | 
							
								  return (~msb32(a ^ b) >>> 0) & 0xffffffff;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Takes a 32 bits integer and returns its population count (number of 1 of
							 | 
						||
| 
								 | 
							
								 * the binary representation).
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {number} x - Target number.
							 | 
						||
| 
								 | 
							
								 * @return {number}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								exports.popcount = function(x) {
							 | 
						||
| 
								 | 
							
								  x -= x >> 1 & 0x55555555;
							 | 
						||
| 
								 | 
							
								  x = (x & 0x33333333) + (x >> 2 & 0x33333333);
							 | 
						||
| 
								 | 
							
								  x = x + (x >> 4) & 0x0f0f0f0f;
							 | 
						||
| 
								 | 
							
								  x += x >> 8;
							 | 
						||
| 
								 | 
							
								  x += x >> 16;
							 | 
						||
| 
								 | 
							
								  return x & 0x7f;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Slightly faster popcount function based on a precomputed table of 8bits
							 | 
						||
| 
								 | 
							
								 * words.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {number} x - Target number.
							 | 
						||
| 
								 | 
							
								 * @return {number}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var TABLE8 = new Uint8Array(Math.pow(2, 8));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								for (var i = 0, l = TABLE8.length; i < l; i++)
							 | 
						||
| 
								 | 
							
								  TABLE8[i] = exports.popcount(i);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.table8Popcount = function(x) {
							 | 
						||
| 
								 | 
							
								  return (
							 | 
						||
| 
								 | 
							
								    TABLE8[x & 0xff] +
							 | 
						||
| 
								 | 
							
								    TABLE8[(x >> 8) & 0xff] +
							 | 
						||
| 
								 | 
							
								    TABLE8[(x >> 16) & 0xff] +
							 | 
						||
| 
								 | 
							
								    TABLE8[(x >> 24) & 0xff]
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								};
							 |