1
+ /**
2
+ * Bit twiddling hacks for JavaScript.
3
+ *
4
+ * Author: Mikola Lysenko
5
+ *
6
+ * Ported from Stanford bit twiddling hack library:
7
+ * http://graphics.stanford.edu/~seander/bithacks.html
8
+ */
9
+
10
+ 'use strict' ;
11
+ 'use restrict' ;
12
+
13
+ // Number of bits in an integer
14
+ export const INT_BITS = 32 ;
15
+ export const INT_MAX = 0x7fffffff ;
16
+ export const INT_MIN = - 1 << ( INT_BITS - 1 ) ;
17
+
18
+ /**
19
+ * Returns -1, 0, +1 depending on sign of x
20
+ *
21
+ * @param {number } v
22
+ * @returns {number }
23
+ */
24
+ export function sign ( v ) {
25
+ return ( v > 0 ) - ( v < 0 ) ;
26
+ }
27
+
28
+ /**
29
+ * Computes absolute value of integer
30
+ *
31
+ * @param {number } v
32
+ * @returns {number }
33
+ */
34
+ export function abs ( v ) {
35
+ let mask = v >> ( INT_BITS - 1 ) ;
36
+ return ( v ^ mask ) - mask ;
37
+ }
38
+
39
+ /**
40
+ * Computes minimum of integers x and y
41
+ *
42
+ * @param {number } x
43
+ * @param {number } y
44
+ * @returns {number }
45
+ */
46
+ export function min ( x , y ) {
47
+ return y ^ ( ( x ^ y ) & - ( x < y ) ) ;
48
+ }
49
+
50
+ /**
51
+ * Computes maximum of integers x and y
52
+ *
53
+ * @param {number } x
54
+ * @param {number } y
55
+ * @returns {number }
56
+ */
57
+ export function max ( x , y ) {
58
+ return x ^ ( ( x ^ y ) & - ( x < y ) ) ;
59
+ }
60
+
61
+ /**
62
+ * Checks if a number is a power of two
63
+ *
64
+ * @param {number } v
65
+ * @returns {boolean }
66
+ */
67
+ export function isPow2 ( v ) {
68
+ return ! ( v & ( v - 1 ) ) && ( ! ! v ) ;
69
+ }
70
+
71
+ /**
72
+ * Computes log base 2 of v
73
+ *
74
+ * @param {number } v
75
+ * @returns {number }
76
+ */
77
+ export function log2 ( v ) {
78
+ let r , shift ;
79
+ r = ( v > 0xFFFF ) << 4 ; v >>>= r ;
80
+ shift = ( v > 0xFF ) << 3 ; v >>>= shift ; r |= shift ;
81
+ shift = ( v > 0xF ) << 2 ; v >>>= shift ; r |= shift ;
82
+ shift = ( v > 0x3 ) << 1 ; v >>>= shift ; r |= shift ;
83
+ return r | ( v >> 1 ) ;
84
+ }
85
+
86
+ /**
87
+ * Computes log base 10 of v
88
+ *
89
+ * @param {number } v
90
+ * @returns {number }
91
+ */
92
+ export function log10 ( v ) {
93
+ return ( v >= 1000000000 ) ? 9 : ( v >= 100000000 ) ? 8 : ( v >= 10000000 ) ? 7 :
94
+ ( v >= 1000000 ) ? 6 : ( v >= 100000 ) ? 5 : ( v >= 10000 ) ? 4 :
95
+ ( v >= 1000 ) ? 3 : ( v >= 100 ) ? 2 : ( v >= 10 ) ? 1 : 0 ;
96
+ }
97
+
98
+ /**
99
+ * Counts number of bits
100
+ *
101
+ * @param {number } v
102
+ * @returns {number }
103
+ */
104
+ export function popCount ( v ) {
105
+ v = v - ( ( v >>> 1 ) & 0x55555555 ) ;
106
+ v = ( v & 0x33333333 ) + ( ( v >>> 2 ) & 0x33333333 ) ;
107
+ return ( ( v + ( v >>> 4 ) & 0xF0F0F0F ) * 0x1010101 ) >>> 24 ;
108
+ }
109
+
110
+ /**
111
+ * Counts number of trailing zeros
112
+ *
113
+ * @param {number } v
114
+ * @returns {number }
115
+ */
116
+ export function countTrailingZeros ( v ) {
117
+ let c = 32 ;
118
+ v &= - v ;
119
+ if ( v ) c -- ;
120
+ if ( v & 0x0000FFFF ) c -= 16 ;
121
+ if ( v & 0x00FF00FF ) c -= 8 ;
122
+ if ( v & 0x0F0F0F0F ) c -= 4 ;
123
+ if ( v & 0x33333333 ) c -= 2 ;
124
+ if ( v & 0x55555555 ) c -= 1 ;
125
+ return c ;
126
+ }
127
+
128
+ /**
129
+ * Rounds to next power of 2
130
+ *
131
+ * @param {number } v
132
+ * @returns {number }
133
+ */
134
+ export function nextPow2 ( v ) {
135
+ v += v === 0 ;
136
+ -- v ;
137
+ v |= v >>> 1 ;
138
+ v |= v >>> 2 ;
139
+ v |= v >>> 4 ;
140
+ v |= v >>> 8 ;
141
+ v |= v >>> 16 ;
142
+ return v + 1 ;
143
+ }
144
+
145
+ /**
146
+ * Rounds down to previous power of 2
147
+ *
148
+ * @param {number } v
149
+ * @returns {number }
150
+ */
151
+ export function prevPow2 ( v ) {
152
+ v |= v >>> 1 ;
153
+ v |= v >>> 2 ;
154
+ v |= v >>> 4 ;
155
+ v |= v >>> 8 ;
156
+ v |= v >>> 16 ;
157
+ return v - ( v >>> 1 ) ;
158
+ }
159
+
160
+ /**
161
+ * Computes parity of word
162
+ *
163
+ * @param {number } v
164
+ * @returns {number }
165
+ */
166
+ export function parity ( v ) {
167
+ v ^= v >>> 16 ;
168
+ v ^= v >>> 8 ;
169
+ v ^= v >>> 4 ;
170
+ v &= 0xf ;
171
+ return ( 0x6996 >>> v ) & 1 ;
172
+ }
173
+
174
+ const REVERSE_TABLE = new Array ( 256 ) ;
175
+
176
+ ( function ( tab ) {
177
+ for ( let i = 0 ; i < 256 ; ++ i ) {
178
+ let v = i , r = i , s = 7 ;
179
+ for ( v >>>= 1 ; v ; v >>>= 1 ) {
180
+ r <<= 1 ;
181
+ r |= v & 1 ;
182
+ -- s ;
183
+ }
184
+ tab [ i ] = ( r << s ) & 0xff ;
185
+ }
186
+ } ) ( REVERSE_TABLE ) ;
187
+
188
+ /**
189
+ * Reverse bits in a 32 bit word
190
+ *
191
+ * @param {number } v
192
+ * @returns {number }
193
+ */
194
+ export function reverse ( v ) {
195
+ return ( REVERSE_TABLE [ v & 0xff ] << 24 ) |
196
+ ( REVERSE_TABLE [ ( v >>> 8 ) & 0xff ] << 16 ) |
197
+ ( REVERSE_TABLE [ ( v >>> 16 ) & 0xff ] << 8 ) |
198
+ REVERSE_TABLE [ ( v >>> 24 ) & 0xff ] ;
199
+ }
200
+
201
+ /**
202
+ * Interleave bits of 2 coordinates with 16 bits. Useful for fast quadtree codes
203
+ *
204
+ * @param {number } x
205
+ * @param {number } y
206
+ * @returns {number }
207
+ */
208
+ export function interleave2 ( x , y ) {
209
+ x &= 0xFFFF ;
210
+ x = ( x | ( x << 8 ) ) & 0x00FF00FF ;
211
+ x = ( x | ( x << 4 ) ) & 0x0F0F0F0F ;
212
+ x = ( x | ( x << 2 ) ) & 0x33333333 ;
213
+ x = ( x | ( x << 1 ) ) & 0x55555555 ;
214
+
215
+ y &= 0xFFFF ;
216
+ y = ( y | ( y << 8 ) ) & 0x00FF00FF ;
217
+ y = ( y | ( y << 4 ) ) & 0x0F0F0F0F ;
218
+ y = ( y | ( y << 2 ) ) & 0x33333333 ;
219
+ y = ( y | ( y << 1 ) ) & 0x55555555 ;
220
+
221
+ return x | ( y << 1 ) ;
222
+ }
223
+
224
+ /**
225
+ * Extracts the nth interleaved component
226
+ *
227
+ * @param {number } v
228
+ * @param {number } n
229
+ * @returns {number }
230
+ */
231
+ export function deinterleave2 ( v , n ) {
232
+ v = ( v >>> n ) & 0x55555555 ;
233
+ v = ( v | ( v >>> 1 ) ) & 0x33333333 ;
234
+ v = ( v | ( v >>> 2 ) ) & 0x0F0F0F0F ;
235
+ v = ( v | ( v >>> 4 ) ) & 0x00FF00FF ;
236
+ v = ( v | ( v >>> 16 ) ) & 0x000FFFF ;
237
+ return ( v << 16 ) >> 16 ;
238
+ }
239
+
240
+ /**
241
+ * Interleave bits of 3 coordinates, each with 10 bits. Useful for fast octree codes
242
+ *
243
+ * @param {number } x
244
+ * @param {number } y
245
+ * @param {number } z
246
+ * @returns {number }
247
+ */
248
+ export function interleave3 ( x , y , z ) {
249
+ x &= 0x3FF ;
250
+ x = ( x | ( x << 16 ) ) & 4278190335 ;
251
+ x = ( x | ( x << 8 ) ) & 251719695 ;
252
+ x = ( x | ( x << 4 ) ) & 3272356035 ;
253
+ x = ( x | ( x << 2 ) ) & 1227133513 ;
254
+
255
+ y &= 0x3FF ;
256
+ y = ( y | ( y << 16 ) ) & 4278190335 ;
257
+ y = ( y | ( y << 8 ) ) & 251719695 ;
258
+ y = ( y | ( y << 4 ) ) & 3272356035 ;
259
+ y = ( y | ( y << 2 ) ) & 1227133513 ;
260
+ x |= ( y << 1 ) ;
261
+
262
+ z &= 0x3FF ;
263
+ z = ( z | ( z << 16 ) ) & 4278190335 ;
264
+ z = ( z | ( z << 8 ) ) & 251719695 ;
265
+ z = ( z | ( z << 4 ) ) & 3272356035 ;
266
+ z = ( z | ( z << 2 ) ) & 1227133513 ;
267
+
268
+ return x | ( z << 2 ) ;
269
+ }
270
+
271
+ /**
272
+ * Extracts nth interleaved component of a 3-tuple
273
+ *
274
+ * @param {number } v
275
+ * @param {number } n
276
+ * @returns {number }
277
+ */
278
+ export function deinterleave3 ( v , n ) {
279
+ v = ( v >>> n ) & 1227133513 ;
280
+ v = ( v | ( v >>> 2 ) ) & 3272356035 ;
281
+ v = ( v | ( v >>> 4 ) ) & 251719695 ;
282
+ v = ( v | ( v >>> 8 ) ) & 4278190335 ;
283
+ v = ( v | ( v >>> 16 ) ) & 0x3FF ;
284
+ return ( v << 22 ) >> 22 ;
285
+ }
286
+
287
+ /**
288
+ * Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page)
289
+ *
290
+ * @param {number } v
291
+ * @returns {number }
292
+ */
293
+ export function nextCombination ( v ) {
294
+ let t = v | ( v - 1 ) ;
295
+ return ( t + 1 ) | ( ( ( ~ t & - ~ t ) - 1 ) >>> ( countTrailingZeros ( v ) + 1 ) ) ;
296
+ }
0 commit comments