Skip to content

Commit

Permalink
feat: Add ctz and clz methods (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxGraey authored Nov 25, 2021
1 parent 93b06bd commit 088e44e
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,12 @@ API
* Long#**not**(): `Long`<br />
Returns the bitwise NOT of this Long.

* Long#**countLeadingZeros**/**clz**(): `number`<br />
Returns count leading zeros of this Long.

* Long#**countTrailingZeros**/**ctz**(): `number`<br />
Returns count trailing zeros of this Long.

* Long#**notEquals**/**neq**/**ne**(other: `Long | number | string`): `boolean`<br />
Tests if this Long's value differs from the specified's.

Expand Down
20 changes: 20 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,26 @@ declare class Long {
*/
not(): Long;

/**
* Returns count leading zeros of this Long.
*/
countLeadingZeros(): number;

/**
* Returns count leading zeros of this Long.
*/
clz(): number;

/**
* Returns count trailing zeros of this Long.
*/
countTrailingZeros(): number;

/**
* Returns count trailing zeros of this Long.
*/
ctz(): number;

/**
* Tests if this Long's value differs from the specified's.
*/
Expand Down
47 changes: 46 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @license
* Copyright 2009 The Closure Library Authors
* Copyright 2020 Daniel Wirtz / The long.js Authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
Expand Down Expand Up @@ -96,6 +96,17 @@ function isLong(obj) {
return (obj && obj["__isLong__"]) === true;
}

/**
* @function
* @param {*} value number
* @returns {number}
* @inner
*/
function ctz32(value) {
var c = Math.clz32(value & -value);
return value ? 31 - c : c;
}

/**
* Tests if the specified object is a Long.
* @function
Expand Down Expand Up @@ -1126,6 +1137,40 @@ LongPrototype.not = function not() {
return fromBits(~this.low, ~this.high, this.unsigned);
};

/**
* Returns count leading zeros of this Long.
* @this {!Long}
* @returns {!number}
*/
LongPrototype.countLeadingZeros = function countLeadingZeros() {
return this.high ? Math.clz32(this.high) : Math.clz32(this.low) + 32;
};

/**
* Returns count leading zeros. This is an alias of {@link Long#countLeadingZeros}.
* @function
* @param {!Long}
* @returns {!number}
*/
LongPrototype.clz = LongPrototype.countLeadingZeros;

/**
* Returns count trailing zeros of this Long.
* @this {!Long}
* @returns {!number}
*/
LongPrototype.countTrailingZeros = function countTrailingZeros() {
return this.low ? ctz32(this.low) : ctz32(this.high) + 32;
};

/**
* Returns count trailing zeros. This is an alias of {@link Long#countTrailingZeros}.
* @function
* @param {!Long}
* @returns {!number}
*/
LongPrototype.ctz = LongPrototype.countTrailingZeros;

/**
* Returns the bitwise AND of this Long and the specified.
* @this {!Long}
Expand Down
18 changes: 18 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ var tests = [ // BEGIN TEST CASES
v = longVal.rotateLeft(32);
assert.deepEqual(v, longValS);
},

function testRotateRight() {
var longVal = Long.fromBits(0x01234567, 0x89ABCDEF);
var longValL = Long.fromBits(0x12345678, 0x9ABCDEF0);
Expand All @@ -191,6 +192,23 @@ var tests = [ // BEGIN TEST CASES
// swap
v = longVal.rotateRight(32);
assert.deepEqual(v, longValS);
},

function testClzAndCtz() {
var longVal0 = Long.fromBits(0, 0);
var longVal1 = Long.fromBits(1, 0);
var longVal2 = Long.fromBits(0, 1);
var longVal3 = Long.fromBits(1, 1);

assert.deepEqual(longVal0.clz(), 64);
assert.deepEqual(longVal1.clz(), 63);
assert.deepEqual(longVal2.clz(), 31);
assert.deepEqual(longVal3.clz(), 31);

assert.deepEqual(longVal0.ctz(), 64);
assert.deepEqual(longVal1.ctz(), 0);
assert.deepEqual(longVal2.ctz(), 32);
assert.deepEqual(longVal3.ctz(), 0);
}

]; // END TEST CASES
Expand Down

0 comments on commit 088e44e

Please sign in to comment.