Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

input-amount rounding big numbers #2463

Open
thatdudemanguy opened this issue Jan 30, 2025 · 0 comments
Open

input-amount rounding big numbers #2463

thatdudemanguy opened this issue Jan 30, 2025 · 0 comments

Comments

@thatdudemanguy
Copy link
Contributor

Bit of a journey, we found out that 20 and 21 characters result into NaN, which throws the IsNumber validation.

Image

I played around with the rounding function to see where the issue lies:

function round(value, decimals) {
  const numberContainsExponent = value?.toString().includes('e');
  if (typeof decimals === 'undefined' || numberContainsExponent) {
    return Number(value);
  }
  return Number(`${Math.round(Number(`${value}e${decimals}`))}e-${decimals}`);
}

Success

round(1111111111111111111, 2);

`${value}e${decimals}` // 1111111111111111200e2
Number(`${value}e${decimals}`)  // 111111111111111110000
`${Math.round(Number(`${value}e${decimals}`))}e-${decimals}` // '111111111111111110000**e-2**'
Number(`${Math.round(Number(`${value}e${decimals}`))}e-${decimals}`); // 1111111111111111000

Fail

round(11111111111111111111, 2) 

`${value}e${decimals}` // '11111111111111110000e2'
Number(`${value}e${decimals}`) // 1.111111111111111e+21
`${Math.round(Number(`${value}e${decimals}`))}e-${decimals}`// '1.111111111111111**e+21e-2**'
Number(`${Math.round(Number(`${value}e${decimals}`))}e-${decimals}`); // NaN

20 and 21 characters, with decimals, seems to be some barrier where the original value does not contain e, but adding the decimals does add it, whereafter the rounding breaks it by adding another exponent, breaking the floating point representation.

`${value}e${decimals}` // '11111111111111110000e2'
Number(`${value}e${decimals}`) // 1.111111111111111e+21
`${Math.round(Number(`${value}e${decimals}`))}e-${decimals}`// '1.111111111111111**e+21e-2**'

Seemed fairly obvious I thought - but they were all of them deceived, it's only after trying to solve the issue where I started noticing the floating point precision issue as well (Notice the input of 11111111111111111111, becoming 11111111111111110000e2). As JS only has 16-ish points of precision (IEEE 754) this issue is of course both for the succeeding, and the failing example.

I got no solution at this point to accept BigDecimals and successfully round them up, tried many things, will try more things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant