113

I found myself in the situation where I wanted to convert a BigInt value to a Number value. Knowing that my value is a safe integer, how can I convert it?

Lucio Paiva
  • 19,015
  • 11
  • 82
  • 104

3 Answers3

167

Turns out it's as easy as passing it to the Number constructor:

const myBigInt = BigInt(10);  // `10n` also works
const myNumber = Number(myBigInt);

Of course, you should bear in mind that your BigInt value must be within [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER] for the conversion to work properly, as stated in the question.

Lucio Paiva
  • 19,015
  • 11
  • 82
  • 104
30

You can use parseInt or Number

const large =  BigInt(309);
const b = parseInt(large);
console.log(b);
const n = Number(large);
console.log(n);
I_Al-thamary
  • 3,385
  • 2
  • 24
  • 37
  • 7
    For performance reasons, I suggest not using `parseInt` for this. Yes, yes, according to the specs, both `parseInt` and `Number` ought to perform the conversion by converting the BigInt to a string before to a number. Nevertheless, the semantics of `parseInt` compared to the semantics of `Number` especially in view of how `BigInt(number)` yields a BigInt makes it more likely that browser vendors will apply more optimizations to `Number(bigValue)` than `parseInt(bigValue)` such that the stringification is internally skipped. Thus, I suggest using `Number` instead of `parseInt` for performance. – Jack G Feb 14 '20 at 16:59
  • @JackGiffin please see this https://stackoverflow.com/questions/4090518/what-is-the-difference-between-parseint-and-number where `parseInt` can be better in some cases – I_Al-thamary Feb 14 '20 at 17:12
  • 1
    I am afraid that I do not understand. I agree that `parseInt` and `Number` have different behaviors, but, for the purposes of converting a BigInt to a number, I can think of no cases where they would differ. Perhaps you could provide an example of where `Number` and `parseInt` differ in conversion of BigInts to numbers to enlighten me. Thank you very much. – Jack G Feb 15 '20 at 19:44
  • @JackGiffin You are totally right in this case of `BigInts` and what I need to show is that `parseInt` and `Number` have different behaviors and you can see the example in the link above. – I_Al-thamary Feb 15 '20 at 20:15
  • 2
    @I_Al-thamary: best practice is to use radix while using `parseInt` – naveen Jan 07 '22 at 13:30
  • if the BigInt value is too large to be represented as a Number, the conversion will result in a loss of precision or may even return NaN, and parseInt will lead to TypeError `const tooBigIntValue = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1); const convertedValue = Number(tooBigIntValue); console.log(tooBigIntValue); // 9007199254740993n console.log(convertedValue); // NaN const convertedValue_parseInt = parseInt(tooBigIntValue)+ BigInt(1); console.log(convertedValue_parseInt); // TypeError` – I_Al-thamary Mar 09 '23 at 18:33
2

Edit: see the discussion in the comments below as to why this answer is not correct. I am leaving the answer up regardless for disambiguation.

You should use either of the static methods:

BigInt.asIntN() - Clamps a BigInt value to a signed integer value, and returns that value. BigInt.asUintN() - Clamps a BigInt value to an unsigned integer value, and returns that value.

as documented here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#static_methods

zr0gravity7
  • 2,917
  • 1
  • 12
  • 33
  • 7
    @zr0gravity7 @naveen, I had the chance to test this and these methods do not return numbers, but BigInt values instead. Their names are misleading, as the `N` suggests `Number`, when in fact they still return BigInt values. Try running `typeof BigInt.asIntN(64, 1n)` to see that it reports `bigint`. So this answer actually does not answer the question. – Lucio Paiva Jan 07 '22 at 14:57
  • 1
    True that. A confusing name. Was reading the documentation. <3 – naveen Jan 07 '22 at 15:42
  • 6
    The explanation of the name is that "intN" is the generalization of "int32", "int64", "int555" and so on; or put differently: "intN" is short for "N-bit integer". The value of this N is the first parameter to the function. An alternative spec could have provided `BigInt.asInt64(x)` and `BigInt.asInt32(x)`, but for maximum flexibility the decision was made to have a single `BigInt.asIntN(N, x)` instead. – jmrk Jan 12 '22 at 11:35
  • 3
    `as(Ui|I)ntN` does not do what you claim nor does this answer OP's question. These functions take a BigInt and return a BigInt modulo 2^N. – Chris_F Aug 03 '22 at 07:32