1. SO: JavaScript BigInt with a gmp-style API, specifically mpfr
- Posted by petelomax Jun 02, 2021
- 1081 views
- Last edited Jun 19, 2021
I posted the question below on SO: https://stackoverflow.com/questions/67814736/javascript-bigint-with-a-gmp-style-api-specifically-mpfr
I am writing a transpiler from my desktop programming language to JavaScript. I use gmp on the desktop, so am writing a thin wrapper to mimic the same entry points but use BigInt under the hood. (NB Emscripten etc NOT involved) So far mpz and mpq are working pretty well, ~30 entry points each, done by hand, so now I am wondering about mpfr. Could mpfr be done as mpq with implied/capped denominator of 10^k (where k can be negative), and accordingly truncated/BigInt numerator? I expect a bit of a struggle with mpfr_const_pi(), mpfr_sin/log/exp(), etc. I say 10^k but am not even certain of that vs 2^k. I have studied https://github.com/MikeMcl/big.js and friends but no offence meant all that seems to pre-date BigInts, and I simply cannot find anything that implements floats via BigInt. In short, what code needs to be in mpfr.js so that the following will work (ideally unaltered), obviously any partial ideas, hints, or tips are just as welcome as a full-blown working example. You can assume (eg) mpz_get_str() is available, or of course you can go with using (say) BigInt.toString() etc directly, and not overly panic about precisely where the decimal point has to go, or any "%.75Rf" related nuances. I just need something to get the ball rolling. <script src="mpfr.js"></script> <script> mpfr_set_default_prec(252); // (enough for 75 decimal places) let one_third = mpfr_init(1); // (ok, non-std syntax, anyway init to 1) mpfr_div_si(one_third,one_third,3); console.log(mpfr_sprintf("%.75Rf",one_third); </script>
Obviously there is more JavaScript and gmp expertise there than here, but no problem also discussing this here.
Update: mpq now working, and a possible start found: https://stackoverflow.com/questions/16742578/bigdecimal-in-javascript/66939244#66939244
Update2: I finally found this https://jrsinclair.com/articles/2020/sick-of-the-jokes-write-your-own-arbitrary-precision-javascript-math-library/ and I've now got pretty much everything I needed working.
While it is exactly what I was looking for, I should point out that it is deeply flawed, for instance there is a frankly outrageous memoize() function liberally applied, which no doubt vastly improved some pointless benchmark but would totally cripple real-world use, and other gross ineffiencies such as exp10(n) returns BigInt(`1${[...new Array(n)].map(() => 0).join("")}`), instead of the much saner 10n**BigInt(n). Nevertheless it is quite spirited and undeniably well meant, with plenty of good ideas.
Should anyone wish to see the results of my efforts I have uploaded the latest version: https://github.com/petelomax/Phix/blob/master/pwa/builtins/mpfr.js