Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

gmp-wasm

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gmp-wasm

Arbitrary-precision Integer, Rational and Float types based on the GMP and MPFR libraries

  • 0.8.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
66
increased by32%
Maintainers
1
Weekly downloads
 
Created
Source

GMP-WASM

npm package Bundle size codecov Build status JSDelivr downloads

Arbitrary-precision Integer, Rational and Float types based on the GMP and MPFR libraries.

Features

  • Provides arbitrary-precision Integer, Rational and Float types
  • Has a lot more features, and in some cases, it's faster than the built-in BigInt type
  • Includes an easy-to-use, high-level wrapper, but low-level functions are also exposed
  • Supports all modern browsers, web workers, Node.js and Deno
  • The WASM binary is bundled as a compressed base64 string (no problems with linking)
  • Works even without Webpack or other bundlers
  • Includes TypeScript type definitions, check API here.
  • Zero dependencies
  • Minified and gzipped bundle has a size of Bundle size
  • 100% open source & transparent build process

Installation

npm i gmp-wasm

It can also be used directly from HTML (via jsDelivr):

<!-- loads the minified library into the global `gmp` variable -->
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm"></script>

<!-- or the non-minified library -->
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm/dist/index.umd.js"></script>

Usage

gmp-wasm also provides a high-level wrapper over the GMP functions. There are three major components:

  • g.Integer() - Wraps integers (MPZ)
  • g.Rational() - Wraps rational numbers (MPQ)
  • g.Float() - Wraps floating-point numbers (MPFR)
const gmp = require('gmp-wasm');

gmp.init().then(({ calculate }) => {
  // calculate() automatically deallocates all objects created within the callback function
  const result = calculate((g) => {
    const six = g.Float(1).add(5);
    return g.Pi().div(six).sin(); // sin(Pi/6) = 0.5
  });
  console.log(result);
});

It is also possible to delay deallocation through the getContext() API:

const gmp = require('gmp-wasm');

gmp.init().then(({ getContext }) => {
  const ctx = getContext();
  let x = ctx.Integer(1);
  for (let i = 2; i < 16; i++) {
    x = x.add(i);
  }
  console.log(x.toString());
  setTimeout(() => ctx.destroy(), 50);
});

The precision and the rounding modes can be set by passing a parameter to the context or to the Float constructor.

const gmp = require('gmp-wasm');

const roundingMode = gmp.FloatRoundingMode.ROUND_TOWARD_NEG_INF;
const options = { precisionBits: 10, roundingMode };

const result = calculate(g => g.Float(1).div(3), options);
// or
const result2 = calculate(g => g.Float(1, options).div(3));
// or
const ctx = getContext(options);
const result3 = ctx.Float(1).div(3).toString();

Predefined constants

  • gmp.Pi
  • gmp.EulerConstant
  • gmp.EulerNumber
  • gmp.Log2
  • gmp.Catalan

Advanced usage

If you want more control and performance you can use the original GMP / MPFR functions.

const gmp = require('gmp-wasm');

gmp.init().then(({ binding }) => {
  // Create first number and initialize it to 30
  const num1Ptr = binding.mpz_t();
  binding.mpz_init_set_si(num1Ptr, 30);
  // Create second number from string. The string needs to be copied into WASM memory
  const num2Ptr = binding.mpz_t();
  const strPtr = binding.malloc_cstr('40');
  binding.mpz_init_set_str(num2Ptr, strPtr, 10);
  // Calculate num1Ptr + num2Ptr, store the result in num1Ptr
  binding.mpz_add(num1Ptr, num1Ptr, num2Ptr);
  // Get result as integer
  console.log(binding.mpz_get_si(num1Ptr));
  // Deallocate memory
  binding.free(strPtr);
  binding.mpz_clears(num1Ptr, num2Ptr);
  binding.mpz_t_frees(num1Ptr, num2Ptr);
});

Sometimes, it's easier and faster to deallocate everything by reinitializing the WASM bindings:

// Deallocate all memory objects created by gmp-wasm
await binding.reset();

Performance

In some cases, this library can provide better performance than the built-in BigInt type.

For example, calculating 8000 digits of Pi using the following formula provides better results:

PI = 3
  + 3 * (1/2) * (1/3) * (1/4)
  + 3 * ((1 * 3)/(2 * 4)) * (1/5) * (1 / (4^2))
  + 3 * ((1 * 3 * 5) / (2 * 4 * 6)) * (1/7) * (1 / (4^3))
  + ...
TestAvg. timeSpeedup
With JS built-in BigInt type130.20 ms1x
gmp-wasm Integer() high-level wrapper87.90 ms1.48x
Same as previous with delayed memory deallocation78.88 ms1.65x
gmp-wasm MPZ low-level functions53.93 ms2.41x
decimal.js 10.3.1 with integer division426.99 ms0.30x
big-integer 1.6.51129.98 ms1x
--------------------------------------------
gmp-wasm Float() high-level wrapper198.31 ms0.66x
Same as previous with delayed memory deallocation191.94 ms0.68x
gmp-wasm MPFR low-level functions135.49 ms0.96x
decimal.js 10.3.1 with float division764.15 ms0.17x
--------------------------------------------
gmp-wasm Float(1).atan().mul(4)0.65 ms200.31x
gmp-wasm Float('0.5').asin().mul(6)17.21 ms7.57x

* These measurements were made with Node.js v16.13 on an Intel Kaby Lake desktop CPU. Source code is here.

Keywords

FAQs

Package last updated on 19 Nov 2021

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc