dnum icon indicating copy to clipboard operation
dnum copied to clipboard

toBigInt api?

Open elee1766 opened this issue 1 year ago • 4 comments

i use dnum to go from token amount in decimals -> absolute token amount.

this is usually done by doing something like

const n = dnum.multiply(dnum.from(decimalAmount), 10n ** BigInt(decimals))

then i need to get the floor of this number as a bigint, to pass to viem, so i do

const bigIntValue = n[0] / 10n ** BigInt(n[1])

it would be useful if there was perhaps an api like.

toBigInt(n:Numberish): bigint


// usage:
const bigIntValue = dnum.toBigInt(n)

would you be open to a PR with something like this? or is there an existing function that i can use to do the same task?

dnum.from(n, 0)[0] maybe? (it seems sort of cursed)

elee1766 avatar Nov 19 '24 22:11 elee1766

@elee1766 Sorry for the late reply − why not using bigint operations directly, e.g. BigInt(parseInt(decimalAmount)) * 10n ** BigInt(decimals)? Could you maybe provide an example to help me understand your use case?

bpierre avatar Dec 30 '24 16:12 bpierre

my use case is to convert a human input amount, say 0.001 usdc, to the raw value, so multiply 0.001*1e6, or even something like, 1.5 eth -> 15e17, etc.

BigInt(parseInt(decimalAmount)) * 10n ** BigInt(decimals) won't work if my decimal amount is not whole, which in most cases, it is.

parseint won't work, and if I use floats, I'll lose my decimals when it gets floors converting to bigint.

imagine I have an input box, and I need to form calldata from it.

elee1766 avatar Dec 30 '24 20:12 elee1766

I see, this is how I usually do this:

function parseInputValue(value: string, decimals: number = 18): Dnum {
  value = value.trim()
    .replace(/\.$/, "")    // remove any trailing "."
    .replace(/^\./, "0."); // 
  return dn.from(value || 0, decimals);
}

Then you could call it like this:

const value = parseInputValue(value, 18)

const data = await client.readContract({
  /* … */
  args: [value[0]]
})

About adding toBigInt(): a concern I have is that it would either require to remove the decimals by rounding it, which would probably not be very useful, or return dnumValue[0], which would be inconsistent with toNumber() and toString() that return the full version of the number (not scaled with the decimals).

bpierre avatar Dec 31 '24 14:12 bpierre

got it, that makes sense. I can be happy with this solution! accessing [0] felt weird, but it's correct for sure so i can do it.

Maybe it would be good to document that this is the "correct" way to do things?

i only say because the original reason i started using this library was specifically to parse floats and scientific notation to then convert into decimal-unscaled values, since parseFloat from viem fails to do scientific notation. perhaps others may be coming to the library with the same needs.

elee1766 avatar Jan 02 '25 19:01 elee1766