Skip to content

Commit

Permalink
chore(common): improve to-bigint
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain committed Sep 3, 2024
1 parent 23675b0 commit cf630d2
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 18 deletions.
25 changes: 14 additions & 11 deletions packages/common/src/numbers/to-bigint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ import {toBigInt} from './to-bigint'

describe('toBigInt', () => {
it.each`
input | decimals | expected
${'123456789'} | ${0} | ${BigInt('123456789')}
${'123456789.000000000000000001'} | ${18} | ${BigInt('123456789000000000000000001')}
${'1'} | ${18} | ${BigInt('1000000000000000000')}
${-1} | ${1} | ${BigInt('-10')}
${123.45} | ${2} | ${BigInt('12345')}
${new BigNumber('-123.456789')} | ${5} | ${BigInt('-12345678')}
${''} | ${5} | ${BigInt('0')}
${new BigNumber(45 * 1e12)} | ${6} | ${BigInt('45000000000000000000')}
input | decimals | abs | expected
${'123456789'} | ${0} | ${undefined} | ${BigInt('123456789')}
${'123456789.000000000000000001'} | ${18} | ${undefined} | ${BigInt('123456789000000000000000001')}
${'AB1CD'} | ${18} | ${undefined} | ${BigInt('1000000000000000000')}
${-1} | ${1} | ${undefined} | ${BigInt('-10')}
${123.45} | ${2} | ${undefined} | ${BigInt('12345')}
${new BigNumber('-123.456789')} | ${5} | ${undefined} | ${BigInt('-12345678')}
${''} | ${5} | ${undefined} | ${BigInt('0')}
${new BigNumber(45 * 1e12)} | ${6} | ${undefined} | ${BigInt('45000000000000000000')}
${new BigNumber(-1)} | ${undefined} | ${undefined} | ${BigInt('-1')}
${new BigNumber(-1)} | ${undefined} | ${true} | ${BigInt('1')}
${new BigNumber(1)} | ${undefined} | ${true} | ${BigInt('1')}
`(
'parses $input with $decimals decimals into $expected',
({input, decimals, expected}) => {
expect(toBigInt(input, decimals)).toBe(expected)
({input, decimals, abs, expected}) => {
expect(toBigInt(input, decimals, abs)).toBe(expected)
},
)
})
27 changes: 20 additions & 7 deletions packages/common/src/numbers/to-bigint.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
import BigNumber from 'bignumber.js'

/**
* @description Converts a number to a bigint in atomic units
* @description Converts to a bigint in atomic units
* don't use this to format inputs use parseDecimal instead
* bare in mind that only '.' is accepted as decimal separator
* if you pass a localized string it will keep only '.-0-9' characters
* which means that your decimal separator can affect the result in languages that use ',' or ' ' as decimal separator
*
* @param quantity string | number | BigNumber
* @param decimalPlaces
* @param {string | number | BigNumber} quantity
* @param {number[0]} decimalPlaces
* @param {boolean} absolute
* @returns bigint with atomic units
*
* @example
* toBigInt('123456789', 0) // => 123456789n
* toBigInt('123456789.000000000000000001', 18) // => 123456789000000000000000001n
* toBigInt('1', 18) // => 1000000000000000000n
* toBigInt('-1', 18) // => -1000000000000000000n
*/
export function toBigInt(
quantity: string | number | BigNumber,
decimalPlaces: number,
decimalPlaces = 0,
absolute = false,
): bigint {
const bigNumber = BigNumber(quantity || 0)
const sanitized =
typeof quantity === 'string'
? quantity.replace(/(?!^-)[^\d.-]/g, '')
: quantity
const bigNumber = BigNumber(sanitized || 0)

const scaledNumber = bigNumber.shiftedBy(decimalPlaces)

return BigInt(scaledNumber.toFixed(0, BigNumber.ROUND_DOWN))
const bi = BigInt(scaledNumber.toFixed(0, BigNumber.ROUND_DOWN))

if (!absolute) return bi

return bi < 0n ? -bi : bi
}

0 comments on commit cf630d2

Please sign in to comment.