{"id":23113068,"url":"https://github.com/daninet/gmp-wasm","last_synced_at":"2025-08-16T19:31:52.150Z","repository":{"id":45315507,"uuid":"425470327","full_name":"Daninet/gmp-wasm","owner":"Daninet","description":"Arbitrary-precision Integer, Rational and Float types based on the GMP and MPFR libraries","archived":false,"fork":false,"pushed_at":"2024-07-07T10:43:09.000Z","size":1628,"stargazers_count":22,"open_issues_count":2,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-15T16:05:34.851Z","etag":null,"topics":["arbitrary-precision","bigint","biginteger","bindings","fast","floating-point","gmp","integer","javascript","mpfr","precision","rational","webassembly"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Daninet.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-07T10:15:29.000Z","updated_at":"2024-12-15T12:37:45.000Z","dependencies_parsed_at":"2024-06-20T23:26:07.332Z","dependency_job_id":"135d05b2-f280-417c-8535-8372ba29e568","html_url":"https://github.com/Daninet/gmp-wasm","commit_stats":{"total_commits":119,"total_committers":3,"mean_commits":"39.666666666666664","dds":"0.38655462184873945","last_synced_commit":"4e372e5a3c4a65f871e1bcaab63c78b29dc80ff8"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daninet%2Fgmp-wasm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daninet%2Fgmp-wasm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daninet%2Fgmp-wasm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daninet%2Fgmp-wasm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Daninet","download_url":"https://codeload.github.com/Daninet/gmp-wasm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230052382,"owners_count":18165383,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arbitrary-precision","bigint","biginteger","bindings","fast","floating-point","gmp","integer","javascript","mpfr","precision","rational","webassembly"],"created_at":"2024-12-17T02:26:56.164Z","updated_at":"2024-12-17T02:26:56.993Z","avatar_url":"https://github.com/Daninet.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GMP-WASM\n\n[![npm package](https://img.shields.io/npm/v/gmp-wasm.svg)](http://npmjs.org/package/gmp-wasm)\n[![codecov](https://codecov.io/gh/Daninet/gmp-wasm/branch/master/graph/badge.svg)](https://codecov.io/gh/Daninet/gmp-wasm)\n[![Build status](https://github.com/Daninet/gmp-wasm/workflows/Build/badge.svg?branch=master)](https://github.com/Daninet/gmp-wasm/actions)\n[![JSDelivr downloads](https://data.jsdelivr.com/v1/package/npm/gmp-wasm/badge)](https://www.jsdelivr.com/package/npm/gmp-wasm)\n\nArbitrary-precision **Integer**, **Rational** and **Float** types based on the [GMP](https://gmplib.org/) and [MPFR](https://www.mpfr.org/) libraries.\n\n## Features\n\n- Supports all modern browsers, web workers, Node.js and Deno\n- Includes an easy-to-use, high-level wrapper, but low-level functions are also exposed\n- Has a lot more features, and in some cases, [it's faster](#performance) than the built-in **BigInt** type\n- The WASM binary is bundled as a compressed base64 string (no problems with linking)\n- Works even without Webpack or other bundlers\n- Includes TypeScript type definitions, check API [here](https://daninet.github.io/gmp-wasm).\n- Zero dependencies\n- Full minified and gzipped bundle has a size of ![Bundle size](https://img.badgesize.io/Daninet/gmp-wasm/binaries/index.umd.min.js?compression=gzip\u0026label=minzipped%20size)\n- It also packages a mini bundle without Float/MPFR operations ![Bundle size](https://img.badgesize.io/Daninet/gmp-wasm/binaries/mini.umd.min.js?compression=gzip\u0026label=minzipped%20size)\n- 100% open source \u0026 [transparent build process](https://github.com/Daninet/gmp-wasm/actions)\n\n## Installation\n\n```\nnpm i gmp-wasm\n```\n\nIt can also be used directly from HTML (via [jsDelivr](https://www.jsdelivr.com/package/npm/gmp-wasm)):\n\n```html\n\u003c!-- loads the full, minified library into the global `gmp` variable --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/gmp-wasm\"\u003e\u003c/script\u003e\n\n\u003c!-- or loads the non-minified library --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/gmp-wasm/dist/index.umd.js\"\u003e\u003c/script\u003e\n\n\u003c!-- or loads the minified library without Float/MPFR functions --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/gmp-wasm/dist/mini.umd.min.js\"\u003e\u003c/script\u003e\n```\n\n## Usage\n\n**gmp-wasm** also provides a high-level wrapper over the GMP functions. There are three major components:\n- `g.Integer()` - Wraps integers (*MPZ*)\n- `g.Rational()` - Wraps rational numbers (*MPQ*)\n- `g.Float()` - Wraps floating-point numbers (*MPFR*)\n\n```js\nconst gmp = require('gmp-wasm');\n\ngmp.init().then(({ calculate }) =\u003e {\n  // calculate() automatically deallocates all objects created within the callback function\n  const result = calculate((g) =\u003e {\n    const six = g.Float(1).add(5);\n    return g.Pi().div(six).sin(); // sin(Pi/6) = 0.5\n  });\n  console.log(result);\n});\n```\n\nIt is also possible to delay deallocation through the `getContext()` API:\n\n```js\nconst gmp = require('gmp-wasm');\n\ngmp.init().then(({ getContext }) =\u003e {\n  const ctx = getContext();\n  let x = ctx.Integer(1);\n  for (let i = 2; i \u003c 16; i++) {\n    x = x.add(i);\n  }\n  console.log(x.toString());\n  setTimeout(() =\u003e ctx.destroy(), 50);\n});\n```\n\nThe precision and the rounding modes can be set by passing a parameter to the context or to the Float constructor.\n\n```js\nconst roundingMode = gmp.FloatRoundingMode.ROUND_DOWN;\nconst options = { precisionBits: 10, roundingMode };\n\nconst result = calculate(g =\u003e g.Float(1).div(3), options);\n// or\nconst result2 = calculate(g =\u003e g.Float(1, options).div(3));\n// or\nconst ctx = getContext(options);\nconst result3 = ctx.Float(1).div(3).toString();\n```\n\n## Predefined constants\n\n- Pi\n- EulerConstant\n- EulerNumber\n- Log2\n- Catalan\n\n## Advanced usage\n\nHigh-level wrapper can be combined with low-level functions:\n\n```js\nconst sum = calculate((g) =\u003e {\n  const a = g.Float(1);\n  const b = g.Float(2);\n  const c = g.Float(0);\n  // c = a + b\n  binding.mpfr_add(c.mpfr_t, a.mpfr_t, b.mpfr_t, 0);\n  return c;\n});\n```\n\nIf you want more control and performance you can use the original GMP / MPFR functions even without high-level wrappers.\n\n```js\nconst gmp = require('gmp-wasm');\n\ngmp.init().then(({ binding }) =\u003e {\n  // Create first number and initialize it to 30\n  const num1Ptr = binding.mpz_t();\n  binding.mpz_init_set_si(num1Ptr, 30);\n  // Create second number from string. The string needs to be copied into WASM memory\n  const num2Ptr = binding.mpz_t();\n  const strPtr = binding.malloc_cstr('40');\n  binding.mpz_init_set_str(num2Ptr, strPtr, 10);\n  // Calculate num1Ptr + num2Ptr, store the result in num1Ptr\n  binding.mpz_add(num1Ptr, num1Ptr, num2Ptr);\n  // Get result as integer\n  console.log(binding.mpz_get_si(num1Ptr));\n  // Deallocate memory\n  binding.free(strPtr);\n  binding.mpz_clears(num1Ptr, num2Ptr);\n  binding.mpz_t_frees(num1Ptr, num2Ptr);\n});\n```\n\nSometimes, it's easier and faster to deallocate everything by reinitializing the WASM bindings:\n```js\n// Deallocate all memory objects created by gmp-wasm\nawait binding.reset();\n```\n\n## Performance\n\nIn some cases, this library can provide better performance than the built-in *BigInt* type.\n\nFor example, calculating 8000 digits of Pi using the following [formula](http://ajennings.net/blog/a-million-digits-of-pi-in-9-lines-of-javascript.html) provides better results:\n\n```\nPI = 3\n  + 3 * (1/2) * (1/3) * (1/4)\n  + 3 * ((1 * 3)/(2 * 4)) * (1/5) * (1 / (4^2))\n  + 3 * ((1 * 3 * 5) / (2 * 4 * 6)) * (1/7) * (1 / (4^3))\n  + ...\n```\n\n| Test                                                                                | Avg. time | Speedup  |\n| ----------------------------------------------------------------------------------- | --------- | -------- |\n| With JS built-in `BigInt` type                                                      | 129 ms    | 1x       |\n| **gmp-wasm** `Integer()` high-level wrapper                                         | 88 ms     | 1.47x    |\n| Same as previous with delayed memory deallocation                                   | 78 ms     | 1.65x    |\n| **gmp-wasm** `MPZ` low-level functions                                              | 53 ms     | 2.43x    |\n| [decimal.js](https://www.npmjs.com/package/decimal.js) 10.3.1 with integer division | 443 ms    | 0.29x    |\n| [big-integer](https://www.npmjs.com/package/big-integer) 1.6.51                     | 129 ms    | 1x       |\n| ----------------------------                                                        | --------  | -------- |\n| **gmp-wasm** `Float()` high-level wrapper                                           | 175 ms    | 0.74x    |\n| Same as previous with delayed memory deallocation                                   | 169 ms    | 0.76x    |\n| **gmp-wasm** `MPFR` low-level functions                                             | 118 ms    | 1.09x    |\n| [decimal.js](https://www.npmjs.com/package/decimal.js) 10.3.1 with float division   | 785 ms    | 0.16x    |\n| ----------------------------                                                        | --------  | -------- |\n| **gmp-wasm** `Float(1).atan().mul(4)`                                               | 0.6 ms    | 215x     |\n| **gmp-wasm** `Float('0.5').asin().mul(6)`                                           | 17 ms     | 7.59x    |\n\n\n\\* These measurements were made with `Node.js v16.14` on an Intel Kaby Lake desktop CPU. Source code is [here](https://github.com/Daninet/gmp-wasm/blob/master/benchmark/calcpi.js).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaninet%2Fgmp-wasm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaninet%2Fgmp-wasm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaninet%2Fgmp-wasm/lists"}