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] | ||
|  |   ); | ||
|  | }; |