Skip to content

Instantly share code, notes, and snippets.

@qntm
Last active July 30, 2026 14:53
Show Gist options
  • Select an option

  • Save qntm/524ebf6de924395e9b07bdcefabeaf2e to your computer and use it in GitHub Desktop.

Select an option

Save qntm/524ebf6de924395e9b07bdcefabeaf2e to your computer and use it in GitHub Desktop.
Compute base-10, base-2 and natural logarithms of JavaScript BigInts
import Decimal from 'decimal.js'
BigInt.log10 = x => Decimal.log(x, 10).toNumber()
BigInt.log2 = x => Decimal.log(x, 2).toNumber()
BigInt.log = x => Decimal.ln(x).toNumber() // `Decimal.log(x, Math.E)` gives incorrect results
/*
This alternate implementation requires no third-party dependencies.
However, due to the limitations of floating point,
the results are sometimes slightly inaccurate.
For example, `BigInt.log2(16n)` evaluates to `3.9999999999999996`
*/
const embiggen = logB => {
const logB10 = logB(10)
return x => {
if (typeof x !== 'bigint' || x < 0n) {
return NaN
}
const s = x.toString(10)
return logB(Number.parseFloat(`0.${s}`)) + s.length * logB10
}
}
BigInt.log10 = embiggen(Math.log10)
BigInt.log2 = embiggen(Math.log2)
BigInt.log = embiggen(Math.log)
@qntm

qntm commented Jul 29, 2026 •

Copy link
Copy Markdown
Author

Usage:

import assert from 'node:assert/strict'
import './biglog-0.js'

assert.equal(BigInt.log10(1n), 0)
assert.equal(BigInt.log10(10n), 1)
assert.equal(BigInt.log10(100n), 2)
assert.equal(BigInt.log10(10n ** 1024n), 1024)

assert.equal(BigInt.log2(1n), 0)
assert.equal(BigInt.log2(2n), 1)
assert.equal(BigInt.log2(16n), 4)
assert.equal(BigInt.log2(2n ** 65536n), 65536)
assert.equal(BigInt.log2(2n ** 65536n / 3n), 65536 - Math.log2(3))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment