# GitHub - js-choi/proposal-bigint-math: Draft specification for supporting...

**URL:** <https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942>\
**Category:** 🦋 Proposals\
**Tags:** proposal\
**Created:** [August 22, 2021, 10:48am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942 "2021-08-22T10:48:34Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yaffle](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/yaffle/32/900_2.png) [@Yaffle](https://es.discourse.group/u/Yaffle)\
**Post date:** [August 22, 2021, 10:48am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/1 "2021-08-22T10:48:34Z")

</div>

There is a proposal to make Math functions working with BigInts - [GitHub - js-choi/proposal-bigint-math: Draft specification for supporting BigInts in JavaScript’s Ma](https://github.com/js-choi/proposal-bigint-math) . I am not the auther and cannot find any discussion, so I am creating this post.

Do you have use cases for one of the below functions?

_Poll ([view on site](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/1))_

Would you like to have one of the below functions:

_Poll ([view on site](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/1))_

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [August 25, 2021, 7:56pm UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/2 "2021-08-25T19:56:15Z")

</div>

Note: bit length and log base 2 are essentially the same thing.

I do have use cases for a clz64, though.

---

<div class="post-metadata">

**Author:** ![Yaffle](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/yaffle/32/900_2.png) [@Yaffle](https://es.discourse.group/u/Yaffle)\
**Post date:** [August 26, 2021, 8:53am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/3 "2021-08-26T08:53:01Z")

</div>

@claudiameadows , hello, thanks for you reply!

log2(x) can be different from bitLength(x) if to allow it to return floating point value... which can be useful sometimes (the current proposal, seems, wants to return bigint values, so you are right)

I think, clz can be computed from bitLength:  
clz64(x) = 64 - bitLength(x), where x is a 64 bit bigint  
clz128(x) = 128 - bitLength(x), where x is a 128 bit bigint

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [August 29, 2021, 11:53pm UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/4 "2021-08-29T23:53:28Z")

</div>

Technically yes, but how often are you to be computing non-floored `log2`s of large integers? Also, floats can't cover the entirety of the result space, so that limits its applicability, and non-integer results for integer input I believe are all transcendental anyways, so you're stuck with infinite decimals regardless.

I wouldn't be against using [GitHub - tc39/proposal-decimal: Built-in decimal datatype in JavaScript](https://github.com/tc39/proposal-decimal) to represent its return value, though. But using standard floats is a _bad_ idea.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 30, 2021, 7:35am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/5 "2021-08-30T07:35:17Z")

</div>

> [@claudiameadows](#):
>
> Also, floats can't cover the entirety of the result space

A little excercise. Given

- `X: BigInt`
- such that `log2(X) > Number.MAX_VALUE`

What is the lower bound of:

- bitLength(X) \>= ?

(and where do you store those bits)?

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [August 31, 2021, 6:30am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/6 "2021-08-31T06:30:58Z")

</div>

It would itself return a bigint, so that's not really a question. And bit length would just return the least amount of bits that could represent the bigint in question as a two's complement integer (i.e. one greater than the floored binary logarithm of that value).

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [August 31, 2021, 7:17am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/7 "2021-08-31T07:17:42Z")

</div>

Your argument was that floats can't cover the entirety of `log2`'s result space. I claim the practical (as in physically possible) result space is smaller than the range of double-precision float.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [August 31, 2021, 7:44am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/8 "2021-08-31T07:44:15Z")

</div>

I'd recommend stating that (with explanations of result ranges, etc.) as a bug against that repo, then. 😉

---

<div class="post-metadata">

**Author:** ![jschoi](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jschoi/32/917_2.png) [@jschoi](https://es.discourse.group/u/jschoi)\
**Post date:** [September 23, 2021, 4:59pm UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/9 "2021-09-23T16:59:47Z")

</div>

I’m taking a look at Yaffle’s poll, and it looks like several people have answered that they would find BigInt `sqrt`, `cbrt`, and `log10` useful. I have been long wondering whether anyone would actually find these useful (they have been removed from the spec due to lack of use cases; the engines don’t want to implement anything without use cases), so it would be great if anyone could share their specific use cases for BigInt `sqrt`, `cbrt`, or `log10`.

([My current vision](https://github.com/tc39/proposal-bigint-math/blob/002ebbbbe26cad005c9ecf32d8e253c6b439a9a8/README.md#vision) is that this initial proposal would overload only a few first `Math` methods, and that the initial proposal would open up the way to new proposals that would further extend `Math` with type-overloaded methods, like `popcnt` or `modPow` or `bitLength` (a truncating `log2`).)

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [September 24, 2021, 9:59am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/10 "2021-09-24T09:59:25Z")

</div>

`log10` is useful for plotting on logarithmic scale, and string formatting. You may want to calculate something with BigInts and then show the result truncated to a number of significant digits.  
edit: Well you could convert to string first and then truncate the string. But then you won't have proper rounding, unless you tinker with the string some more.

That being said, I would find it really weird if `logN` truncated the result to BigInt, instead of returning a Number. It would complicate the plotting on logarithmic scale use case. ~~You'd basically need to first multiply by 1000 and then do the `log10` to get a usable result.~~

edit 2: damn I'm dumb today. Multiplying of course wouldn't help at all, it would only add a constant to all results, but not make them "smoother". You'd need to pow like `log10(x ** 20)` to get a smoother plot.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [September 25, 2021, 12:06am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/11 "2021-09-25T00:06:53Z")

</div>

I thought for string display you divide by a power of 10, not take a decimal logarithm.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [September 25, 2021, 12:12am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/12 "2021-09-25T00:12:09Z")

</div>

Yea but what power of 10? If you want 50 significant digits, you divide by `10 ** (log10(x) - 50)`.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [September 25, 2021, 1:06am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/13 "2021-09-25T01:06:37Z")

</div>

[It's `num / (10 ** precision)` mod a few edge cases.](https://github.com/v8/v8/blob/03ff1b6dd6214d9c2f48c059184f26c4166a12ed/src/base/numbers/fast-dtoa.cc#L32) Logarithms simply count digits and aside from very large bignum arithmetic you can get away by just repeated division because the time it takes to do that is negligible compared to the cost of everything else and all you really need is a floored base 10 logarithm.

For bigints, as long as you have a "find first set" or related algorithm (like "count leading zeroes"), you can still do that part extremely efficiently.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [September 25, 2021, 9:06am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/14 "2021-09-25T09:06:00Z")

</div>

> [@claudiameadows](#):
>
> [It's `num / (10 ** precision)` mod a few edge cases.](https://github.com/v8/v8/blob/03ff1b6dd6214d9c2f48c059184f26c4166a12ed/src/base/numbers/fast-dtoa.cc#L32)

This statement is wrong. The link is not even related; I assume you meant to instead link to [this function](https://github.com/v8/v8/blob/03ff1b6dd6214d9c2f48c059184f26c4166a12ed/src/base/numbers/fast-dtoa.cc#L208) in that code — notice how what it does is approximating `log10(x)`.

When you have `x = 10 **500`, and want to print it in a readable form, you don't cut `precision` digits; you cut `d = (log10(x) - precision)` digits and append `"E"+d`. For example with `precision = 5` the output would be `"100000E495"` (or some other form of the same, like `"100000 * 10**495"`). You may also cut trailing zeros, but you can only do that after cutting `d` excess digits, for which you need to know `log10(x)`.

> [@claudiameadows](#):
>
> Logarithms simply count digits and aside from very large bignum arithmetic you can get away by just repeated division because the time it takes to do that is negligible compared to the cost of everything else and all you really need is a floored base 10 logarithm.

Repeated division is just a silly way of reimplementing logarithm. You could get fancy a use binary search to find the `d`, which is slightly more efficient and complicated way of reimplementing logarithm.

> [@claudiameadows](#):
>
> For bigints, as long as you have a "find first set" or related algorithm (like "count leading zeroes"), you can still do that part extremely efficiently.

Yes, "find first set" would help reimplementing floored `log10` more efficiently. "count leading zeros" only makes sense for fixed-width integers, not for BigInt.  
Question is: why should everyone who wants to stringify large BigInts need to reimplement `log10`?

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [September 26, 2021, 8:07am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/15 "2021-09-26T08:07:37Z")

</div>

> [@lightmare](#):
>
> This statement is wrong. The link is not even related; I assume you meant to instead link to [this function](https://github.com/v8/v8/blob/03ff1b6dd6214d9c2f48c059184f26c4166a12ed/src/base/numbers/fast-dtoa.cc#L208) in that code — notice how what it does is approximating `log10(x)`.

I'll stand corrected. I misread the code.

> [@lightmare](#):
>
> Repeated division is just a silly way of reimplementing logarithm. You could get fancy a use binary search to find the `d`, which is slightly more efficient and complicated way of reimplementing logarithm.

I'm aware, and was trying to implicitly acknowledge this in the comment you quoted. 😉

> [@lightmare](#):
>
> Yes, "find first set" would help reimplementing floored `log10` more efficiently. "count leading zeros" only makes sense for fixed-width integers, not for BigInt.

Why I said "or related" - there's several ways of doing "find first set". Even something as simple as bit length would also be sufficient (and honestly, that's probably what I should've suggested in the first place).

> [@lightmare](#):
>
> Question is: why should everyone who wants to stringify large BigInts need to reimplement `log10`?

I do get that concern, but I'm not convinced adding a decimal logarithm is worth it when that could just be addressed by adding `.toPrecision` to bigints to align with floating point numbers and suddenly nobody's having to roll their own stringifier.

There's of course other use cases, but I wouldn't consider them common by any stretch.

---

<div class="post-metadata">

**Author:** ![Rudxain](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/rudxain/32/2272_2.png) [@Rudxain](https://es.discourse.group/u/Rudxain)\
**Post date:** [November 1, 2024, 1:40am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/16 "2024-11-01T01:40:46Z")

</div>

In practice, that's always true. But in theory, a `BigInt` could be bigger than [G(64)](https://en.wikipedia.org/wiki/Graham%27s_number), as the spec places no hard-coded limits on their size.

It's unfortunate that `Map` and `Set` came before `BigInt`s, because (unlike `String` and `Array`, whose `length`s fit in a 64bit register) their [internal size is unbounded, but gets converted to a `Float64` by their getter](https://tc39.es/ecma262/multipage/keyed-collections.html#sec-get-map.prototype.size)

And `float`s lose fractional precision as the order-of-magnitude increases

---

<div class="post-metadata">

**Author:** ![jschoi](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jschoi/32/917_2.png) [@jschoi](https://es.discourse.group/u/jschoi)\
**Post date:** [April 4, 2025, 3:12am UTC](https://es.discourse.group/t/github-js-choi-proposal-bigint-math-draft-specification-for-supporting/942/17 "2025-04-04T03:12:37Z")

</div>

For those subscribed to this thread, I’ve gotten a little more free time to volunteer at TC39. I’ve made an update to BigInt math at [General philosophy and vision · Issue #13 · tc39/proposal-bigint-math · GitHub](https://github.com/tc39/proposal-bigint-math/issues/13), which reluctantly changes from my original vision of overloading Math’s functions to simply putting new functions on BigInt. Please feel free to read the update’s reasoning and leave feedback there.
