Skip to content

Commit 088e44e

Browse files
authored
feat: Add ctz and clz methods (#105)
1 parent 93b06bd commit 088e44e

File tree

4 files changed

+90
-1
lines changed

4 files changed

+90
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ API
202202
* Long#**not**(): `Long`<br />
203203
Returns the bitwise NOT of this Long.
204204

205+
* Long#**countLeadingZeros**/**clz**(): `number`<br />
206+
Returns count leading zeros of this Long.
207+
208+
* Long#**countTrailingZeros**/**ctz**(): `number`<br />
209+
Returns count trailing zeros of this Long.
210+
205211
* Long#**notEquals**/**neq**/**ne**(other: `Long | number | string`): `boolean`<br />
206212
Tests if this Long's value differs from the specified's.
207213

index.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,26 @@ declare class Long {
289289
*/
290290
not(): Long;
291291

292+
/**
293+
* Returns count leading zeros of this Long.
294+
*/
295+
countLeadingZeros(): number;
296+
297+
/**
298+
* Returns count leading zeros of this Long.
299+
*/
300+
clz(): number;
301+
302+
/**
303+
* Returns count trailing zeros of this Long.
304+
*/
305+
countTrailingZeros(): number;
306+
307+
/**
308+
* Returns count trailing zeros of this Long.
309+
*/
310+
ctz(): number;
311+
292312
/**
293313
* Tests if this Long's value differs from the specified's.
294314
*/

index.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @license
33
* Copyright 2009 The Closure Library Authors
44
* Copyright 2020 Daniel Wirtz / The long.js Authors.
5-
*
5+
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
88
* You may obtain a copy of the License at
@@ -96,6 +96,17 @@ function isLong(obj) {
9696
return (obj && obj["__isLong__"]) === true;
9797
}
9898

99+
/**
100+
* @function
101+
* @param {*} value number
102+
* @returns {number}
103+
* @inner
104+
*/
105+
function ctz32(value) {
106+
var c = Math.clz32(value & -value);
107+
return value ? 31 - c : c;
108+
}
109+
99110
/**
100111
* Tests if the specified object is a Long.
101112
* @function
@@ -1126,6 +1137,40 @@ LongPrototype.not = function not() {
11261137
return fromBits(~this.low, ~this.high, this.unsigned);
11271138
};
11281139

1140+
/**
1141+
* Returns count leading zeros of this Long.
1142+
* @this {!Long}
1143+
* @returns {!number}
1144+
*/
1145+
LongPrototype.countLeadingZeros = function countLeadingZeros() {
1146+
return this.high ? Math.clz32(this.high) : Math.clz32(this.low) + 32;
1147+
};
1148+
1149+
/**
1150+
* Returns count leading zeros. This is an alias of {@link Long#countLeadingZeros}.
1151+
* @function
1152+
* @param {!Long}
1153+
* @returns {!number}
1154+
*/
1155+
LongPrototype.clz = LongPrototype.countLeadingZeros;
1156+
1157+
/**
1158+
* Returns count trailing zeros of this Long.
1159+
* @this {!Long}
1160+
* @returns {!number}
1161+
*/
1162+
LongPrototype.countTrailingZeros = function countTrailingZeros() {
1163+
return this.low ? ctz32(this.low) : ctz32(this.high) + 32;
1164+
};
1165+
1166+
/**
1167+
* Returns count trailing zeros. This is an alias of {@link Long#countTrailingZeros}.
1168+
* @function
1169+
* @param {!Long}
1170+
* @returns {!number}
1171+
*/
1172+
LongPrototype.ctz = LongPrototype.countTrailingZeros;
1173+
11291174
/**
11301175
* Returns the bitwise AND of this Long and the specified.
11311176
* @this {!Long}

tests/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ var tests = [ // BEGIN TEST CASES
177177
v = longVal.rotateLeft(32);
178178
assert.deepEqual(v, longValS);
179179
},
180+
180181
function testRotateRight() {
181182
var longVal = Long.fromBits(0x01234567, 0x89ABCDEF);
182183
var longValL = Long.fromBits(0x12345678, 0x9ABCDEF0);
@@ -191,6 +192,23 @@ var tests = [ // BEGIN TEST CASES
191192
// swap
192193
v = longVal.rotateRight(32);
193194
assert.deepEqual(v, longValS);
195+
},
196+
197+
function testClzAndCtz() {
198+
var longVal0 = Long.fromBits(0, 0);
199+
var longVal1 = Long.fromBits(1, 0);
200+
var longVal2 = Long.fromBits(0, 1);
201+
var longVal3 = Long.fromBits(1, 1);
202+
203+
assert.deepEqual(longVal0.clz(), 64);
204+
assert.deepEqual(longVal1.clz(), 63);
205+
assert.deepEqual(longVal2.clz(), 31);
206+
assert.deepEqual(longVal3.clz(), 31);
207+
208+
assert.deepEqual(longVal0.ctz(), 64);
209+
assert.deepEqual(longVal1.ctz(), 0);
210+
assert.deepEqual(longVal2.ctz(), 32);
211+
assert.deepEqual(longVal3.ctz(), 0);
194212
}
195213

196214
]; // END TEST CASES

0 commit comments

Comments
 (0)