Skip to content

Commit d228874

Browse files
fix(js): fix bitLength function
1 parent 559bd00 commit d228874

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

kbigint/src/javascript/kbigint-utils.mjs

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,31 @@ export function sign(value) {
1313
/**
1414
* Count the total number of bits in the value.
1515
*
16-
* @param value {bigint}
17-
* @return {number}
18-
* @see https://stackoverflow.com/a/76616288/21974435
16+
* @param {bigint} value
17+
* @returns {number}
1918
*/
2019
export function bitLength(value) {
21-
const n = value >= 0n ? value : ~value;
22-
const i = (n.toString(16).length - 1) >> 2;
23-
return i + 32 - Math.clz32(Number(n >> BigInt(i)))
20+
if (value < 0n) value = ~value;
21+
if (value === 0n) return 0;
22+
23+
let low = 0n, high = 1n;
24+
25+
while ((value >> high) !== 0n) high <<= 1n;
26+
27+
while (high - low > 1n) {
28+
const mid = (low + high) >> 1n;
29+
if ((value >> mid) !== 0n) low = mid;
30+
else high = mid;
31+
}
32+
33+
return Number(low) + 1;
2434
}
2535

2636
/**
2737
* Count the number of set bits in the value.
2838
*
29-
* @param value {bigint}
30-
* @return {number}
39+
* @param {bigint} value
40+
* @returns {number}
3141
* @see https://stackoverflow.com/a/72518920/21974435
3242
*/
3343
export function bitCount(value) {
@@ -70,7 +80,7 @@ export function cmp(a, b) {
7080
}
7181

7282
/**
73-
* Find the Greatest Common Divisor
83+
* Find the Greatest Common Divisor of the two values.
7484
*
7585
* @param {bigint} a
7686
* @param {bigint} b
@@ -95,8 +105,8 @@ export function pow(value, n) {
95105
/**
96106
* Convert a {@link BigInt} to an {@link Int8Array}.
97107
*
98-
* @param value {bigint}
99-
* @return {Int8Array}
108+
* @param {bigint} value
109+
* @returns {Int8Array}
100110
* @see https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/
101111
*/
102112
export function toByteArray(value) {
@@ -113,8 +123,8 @@ export function toByteArray(value) {
113123
/**
114124
* Convert a numeric {@link Array} to a {@link BigInt}.
115125
*
116-
* @param bytes {number[] | ArrayLike<number>}
117-
* @return {bigint}
126+
* @param {number[] | ArrayLike<number>} bytes
127+
* @returns {bigint}
118128
* @see https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/
119129
*/
120130
export function fromByteArray(bytes) {
@@ -140,17 +150,17 @@ function newtonRoot(n, k) {
140150

141151
/**
142152
* @private
143-
* @param str {string}
144-
* @return {string}
153+
* @param {string} str
154+
* @returns {string}
145155
*/
146156
function bitFlip(str) {
147157
return Array.from(str, i => i === '0' ? '1' : '0').join('')
148158
}
149159

150160
/**
151161
* @private
152-
* @param bn {bigint}
153-
* @return {bigint}
162+
* @param {bigint} bn
163+
* @returns {bigint}
154164
* @see https://coolaj86.com/articles/convert-decimal-to-hex-with-js-bigints/
155165
*/
156166
function bitNot(bn) {
@@ -163,17 +173,17 @@ function bitNot(bn) {
163173

164174
/**
165175
* @private
166-
* @param hex {string}
167-
* @return {number}
176+
* @param {string} hex
177+
* @returns {number}
168178
*/
169179
function highByte(hex) {
170180
return parseInt(hex.slice(0, 2), 16);
171181
}
172182

173183
/**
174184
* @private
175-
* @param hex {string}
176-
* @return {bigint}
185+
* @param {string} hex
186+
* @returns {bigint}
177187
* @see https://coolaj86.com/articles/convert-hex-to-decimal-with-js-bigints/
178188
*/
179189
function hexToBn(hex) {
@@ -189,8 +199,8 @@ function hexToBn(hex) {
189199

190200
/**
191201
* @private
192-
* @param bn {bigint}
193-
* @return {string}
202+
* @param {bigint} bn
203+
* @returns {string}
194204
* @see https://coolaj86.com/articles/convert-decimal-to-hex-with-js-bigints/
195205
*/
196206
function bnToHex(bn) {

kbigint/src/jsMain/kotlin/io/github/observeroftime/kbigint/KBigInt.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ actual class KBigInt private constructor(@JsExternalArgument private var value:
4141
*
4242
* @since 0.3.0
4343
*/
44+
@ExperimentalMultiplatform
4445
actual val bitLength: Int
4546
get() = KBigIntUtils.bitLength(value)
4647

kbigint/src/jsTest/kotlin/io/github/observeroftime/kbigint/KBigIntTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ actual class KBigIntTest {
1616
}
1717

1818
@Test
19+
@OptIn(ExperimentalMultiplatform::class)
1920
actual fun testBits() {
2021
val a = KBigInt(1024)
2122
val b = KBigInt(-1024)

0 commit comments

Comments
 (0)