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

Can't convert BigInt to Decimal without setting its value to 0 #142

Open
James103 opened this issue Jan 7, 2023 · 8 comments
Open

Can't convert BigInt to Decimal without setting its value to 0 #142

James103 opened this issue Jan 7, 2023 · 8 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@James103
Copy link

James103 commented Jan 7, 2023

Currently (latest break_eternity.js version as of 2023-01-07), attempting to convert a BigInt value to Decimal will return 0. Furthermore, a string that represents a number (generated by BigInt.toString()) will also return 0 if the number the string represents is at least 21024.

Console output with test cases:

new Decimal(String(2n**1022n)).toString() // 1
'4.494232837155819e307'

new Decimal(String(2n**1032n)).toString() // 2
'0'

new Decimal(1234n).toString() // 3
'0'

new Decimal(2n**1234n).toString() // 4
'0'
  1. Correct
  2. Incorrect; should be 21032 or about 4.602094e310
  3. Incorrect; should be 1234
  4. Incorrect; should be 21234 or about 2.958112e371

Discovered whilst writing migration code for an incremental game to convert various save data from BigInt values to their proper Decimals.

@Patashu Patashu added the bug Something isn't working label Jan 8, 2023
@Patashu
Copy link
Owner

Patashu commented Jan 8, 2023

Woah, I haven't seen this '2n' thing before. Is it a new Javascript feature?

@Patashu Patashu added the enhancement New feature or request label Jan 8, 2023
@James103
Copy link
Author

James103 commented Jan 8, 2023

Woah, I haven't seen this '2n' thing before. Is it a new Javascript feature?

The syntax used describes something called BigInts, which are supported on the most recent version of all major browsers. BigInts effectively allow storing numbers much larger than 21024 with full precision (down to the nearest whole number), with their size effectively only being limited only by available memory.

For more information on BigInts, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

@Patashu
Copy link
Owner

Patashu commented Jan 8, 2023

Cutting edge! I'll take a look at supporting BigInts if I find the time and mood.

@James103
Copy link
Author

James103 commented Jan 8, 2023

You can convert a BigInt to a String with String(bigint) or bigint.toString() and you can construct a Decimal from a string of digits with new Decimal(string). However, Decimal.fromString fails to properly parse strings of digits that are more than 309 digits long, as such strings become Infinity when coerced to Number.

Number("1".repeat(309))
1.1111111111111112e+308

Number("1".repeat(310))
Infinity

@Patashu
Copy link
Owner

Patashu commented Jan 8, 2023

I guess it'd be sufficient to detect the string is longer than 300 digits, grab the first 18 of them, and turn it into mantissa and exponent.

1231234md5 added a commit to 1231234md5/break_eternity.js that referenced this issue Jan 13, 2023
Now, lambert-w has 200 iterations to get more accurate results.
Also, converting BigInts to Decimals is now possible! (new Decimal(12345n**12345n).toString() outputs 2.867865225007882e50509)
1231234md5 added a commit to 1231234md5/break_eternity.js that referenced this issue Jan 13, 2023
1231234md5 added a commit to 1231234md5/break_eternity.js that referenced this issue Jan 13, 2023
1231234md5 added a commit to 1231234md5/break_eternity.js that referenced this issue Jan 13, 2023
1231234md5 added a commit to 1231234md5/break_eternity.js that referenced this issue Jan 13, 2023
1231234md5 added a commit to 1231234md5/break_eternity.js that referenced this issue Jan 13, 2023
@1231234md5
Copy link

#145 will fix it

@jakub791
Copy link

jakub791 commented Feb 3, 2023

I guess it'd be sufficient to detect the string is longer than 300 digits, grab the first 18 of them, and turn it into mantissa and exponent.

Couldn't you toString() the bigint, remove the n from the string then let toString() method do it's job as usual?

@1231234md5
Copy link

I guess it'd be sufficient to detect the string is longer than 300 digits, grab the first 18 of them, and turn it into mantissa and exponent.

Couldn't you toString() the bigint, remove the n from the string then let toString() method do it's job as usual?

but that's what #145 does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants