Skip to content

Commit

Permalink
Merge pull request #42 from distributed-lab/fix/bn-parse-exponential-…
Browse files Browse the repository at this point in the history
…notation

fix BN.fromRaw value with exponential notation
  • Loading branch information
napalmpapalam authored Nov 7, 2023
2 parents 8aafb5f + 7cfefad commit 19b0403
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 9 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## [1.0.0-rc.8] - 2023-11-07
### Fixed
- `@distributedlab/tools` - `BN.fromRaw` parsing string value with the exponential notation

## [1.0.0-rc.7] - 2023-09-25
### Added
- `@distributedlab/w3p` - WalletConnect EVM provider
Expand Down Expand Up @@ -336,7 +340,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

[old repo]: https://github.com/distributed-lab/web-kit-old

[Unreleased]: https://github.com/distributed-lab/web-kit/compare/1.0.0-rc.7...HEAD
[Unreleased]: https://github.com/distributed-lab/web-kit/compare/1.0.0-rc.8...HEAD
[1.0.0-rc.8]: https://github.com/distributed-lab/web-kit/compare/1.0.0-rc.7...1.0.0-rc.8
[1.0.0-rc.7]: https://github.com/distributed-lab/web-kit/compare/1.0.0-rc.6...1.0.0-rc.7
[1.0.0-rc.6]: https://github.com/distributed-lab/web-kit/compare/1.0.0-rc.5...1.0.0-rc.6
[1.0.0-rc.5]: https://github.com/distributed-lab/web-kit/compare/1.0.0-rc.4...1.0.0-rc.5
Expand Down
2 changes: 1 addition & 1 deletion packages/fetcher/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@distributedlab/fetcher",
"version": "1.0.0-rc.7",
"version": "1.0.0-rc.8",
"description": "Fetch API wrapper with the extended functionality and simple interface",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/jac/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@distributedlab/jac",
"version": "1.0.0-rc.7",
"version": "1.0.0-rc.8",
"description": "A library for constructing JSON-API compliant requests and responses",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/reactivity/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@distributedlab/reactivity",
"version": "1.0.0-rc.7",
"version": "1.0.0-rc.8",
"description": "Implementation of the reactivity connections to propagate changes between objects",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/tools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@distributedlab/tools",
"version": "1.0.0-rc.7",
"version": "1.0.0-rc.8",
"description": "Collection of common utility functions and classes",
"repository": {
"type": "git",
Expand Down
83 changes: 83 additions & 0 deletions packages/tools/src/bn/bn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,89 @@ describe('performs BN unit test', () => {
expect(bn.raw).toBe(100000000000000000000000000n)
})
})

describe('if value with exponential notation', () => {
describe('without fraction part', () => {
test('with positive exponent', () => {
const bn = BN.fromRaw('1e+2', 6)
expect(bn.value).toBe('100000000')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(10000000000000000000000000000n)
})

test('with negative exponent which equals value length', () => {
const bn = BN.fromRaw('33e-2', 6)
expect(bn.value).toBe('330000')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(33000000000000000000000000n)
})

test('with negative exponent which more than value length', () => {
const bn = BN.fromRaw('22e-10', 18)
expect(bn.value).toBe('2200000000')
expect(bn.decimals).toBe(18)
expect(bn.raw).toBe(220000000000000000n)
})

test('with negative exponent which more than value length [2]', () => {
const bn = BN.fromRaw('22e-10', 6)
expect(bn.value).toBe('0')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(220000000000000000n)
})

test('with negative exponent which more than BN precision', () => {
const bn = BN.fromRaw(`22e-${BN.precision + 4}`, 6)
expect(bn.value).toBe('0')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(0n)
})
})

describe('with fraction part', () => {
test('with positive exponent', () => {
const bn = BN.fromRaw('3.5e+4', 6)
expect(bn.value).toBe('35000000000')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(3500000000000000000000000000000n)
})

test('with positive exponent and whole is zero', () => {
const bn = BN.fromRaw('0.1e+5', 6)
expect(bn.value).toBe('10000000000')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(1000000000000000000000000000000n)
})

test('with negative exponent which equals value length', () => {
const bn = BN.fromRaw('0.33e-3', 6)
expect(bn.value).toBe('330')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(33000000000000000000000n)
})

test('with negative exponent which more than value length', () => {
const bn = BN.fromRaw('1.34e-10', 18)
expect(bn.value).toBe('134000000')
expect(bn.decimals).toBe(18)
expect(bn.raw).toBe(13400000000000000n)
})

test('with negative exponent which equals BN precision', () => {
const bn = BN.fromRaw(`1.3e-${BN.precision}`, 6)
expect(bn.value).toBe('0')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(1n)
})

test('with negative exponent which more than BN precision', () => {
const bn = BN.fromRaw(`2.2e-${BN.precision + 4}`, 6)
expect(bn.value).toBe('0')
expect(bn.decimals).toBe(6)
expect(bn.raw).toBe(0n)
})
})
})
})
})

Expand Down
21 changes: 19 additions & 2 deletions packages/tools/src/bn/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,27 @@ export const parseNumberString = (_value: string): string => {
const isFractionalZero = !fractional || fractional.match(/^(0+)$/)
const isWholeZero = whole === '0' || whole.replaceAll('0', '') === ''

const exponential = match[4]
const exponentialSign = exponential?.slice(1, 2)
const exponentialDecimals = Number(exponential?.slice(2))

if (isWholeZero && isFractionalZero) return '0'
if (!fractional) return whole.padEnd(whole.length + BN.precision, '0')

return (isWholeZero ? '' : whole) + fractional.padEnd(BN.precision, '0')
let result = whole.padEnd(whole.length + BN.precision, '0')

if (!fractional) return fromExp(result, exponentialSign, exponentialDecimals)

result = (isWholeZero ? '' : whole) + fractional.padEnd(BN.precision, '0')

return fromExp(result, exponentialSign, exponentialDecimals)
}

const fromExp = (value: string, sign?: string, decimals?: number) => {
if (!sign || !decimals) return value
if (sign === '+') return value.padEnd(value.length + decimals, '0')
if (decimals > value.length) return '0'

return value.slice(0, value.length - decimals)
}

export const parseConfig = (config: BnConfigLike): BnConfig => {
Expand Down
2 changes: 1 addition & 1 deletion packages/tools/src/const/bn.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const DEFAULT_BN_PRECISION = 26
export const NUMBER_REGEX = /^(-?)(\d+)(\.\d+)?$/
export const NUMBER_REGEX = /^(-?)(\d+)(\.\d+)?([eE][-+]?\d+)?$/
export const HEX_REGEX = /^0x[0-9a-f]+$/i
2 changes: 1 addition & 1 deletion packages/w3p/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@distributedlab/w3p",
"version": "1.0.0-rc.7",
"version": "1.0.0-rc.8",
"description": "Wrapper for Web3 Providers",
"repository": {
"type": "git",
Expand Down

0 comments on commit 19b0403

Please sign in to comment.