npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tdurica/zmath

v1.0.2

Published

Wrapper for exact-math purposed for use with Solidity!

Downloads

132

Readme

zmath

Wrapper for exact-math purposed for use with Solidity!

Problem - Solution

The general idea here is that it can be preferable to avoid BigInt, BigNumber, and even the number datatype when working with or simulating smart contract code.

We would instead favor string representation for all numbers and mathematical operation. This results in less conversion code and a greater degree of human-readability and debug-ability while authoring and debugging our projects.
We like the simplicity and predictability afforded us by working with strings.

When we begin to work this way, we tend to discover a propensity to lean all the way in to it.

Zmath aims to be the perfect utility for leaning completely into string math dependency.

Tersity

To reduce cognitive load in our implementations, zmath's function names are short and shorthandy, and import individually rather than under a namespace.

Sanitization

Zmath internally applies a custom sanitizer to most operations which automatically handles basic type/format conversions, and prettifies and corrects values, within reason. This lends to a graceful DX that keeps us moving.

For example:

  • 0 becomes "0" (numbers and BigNumbers always convert to string)
  • ".0" becomes "0.0" (leading decimal prefixed with 0)
  • "0." becomes "0" (trailing decimal removed)
  • "00100.00100" becomes "100.001"
  • "11.22.33" throws an error
  • ,_$% characters are always removed

Error Reporting

Zmath has pretty good error reporting when it decides we've gone too far off the rails, and the solidity series of functions adds more checks and reporting on top.

Include

Zmath supports both CommonJS require() and ESM imports

import {
  sAdd,sSub,sMul,sDiv,sAddRay,_Add,_Sub,_Mul,_Div,_AddRay,_Chk,
  sRnd,sAbs,_Flr,sFlr,sPow,sFla,sExp,sHR,hrExp,sNewtonSqRt,sChg,sScaleToPcts,nScaleToPcts,
  sIs,sIs0,sIsGT,sIsLT,sIsGTorEq,sIsLTorEq,sIsEq,sIsNotEq,
  k0,num,sEthToWei,first4,last4,surr4s,inTenMinutes,weiToUSD,usdToWei,
  abbrvNum,balToHrTuple,getAmountOut,adjustBrightness,sUint256max,sPpow2_128,sJsMaxSafeInt,
} from '@tdurica/zmath';

/* - OR - */

const {
  sAdd,sSub,sMul,sDiv,sAddRay,_Add,_Sub,_Mul,_Div,_AddRay,_Chk,
  sRnd,sAbs,_Flr,sFlr,sPow,sFla,sExp,sHR,hrExp,sNewtonSqRt,sChg,sScaleToPcts,nScaleToPcts,
  sIs,sIs0,sIsGT,sIsLT,sIsGTorEq,sIsLTorEq,sIsEq,sIsNotEq,
  k0,num,sEthToWei,first4,last4,surr4s,inTenMinutes,weiToUSD,usdToWei,
  abbrvNum,balToHrTuple,getAmountOut,adjustBrightness,sUint256max,sPpow2_128,sJsMaxSafeInt,
} = require('@tdurica/zmath');

Usages


// useful constants
sUint256max; // "115792089237316195423570985008687907853269984665640564039457584007913129639935"
sPpow2_128; // "340282366920938463463374607431768211456" //TODO: doublecheck or explain var name
sJsMaxSafeInt; // "9007199254740991"

// general utilities
k0({ key: 'value' }); // "key" //TODO: rename, extend implementation
num('42'); // 42
sEthToWei('1.5'); // "1500000000000000000"
first4('123456789'); // "1234"
last4('123456789'); // "6789"
surr4s('1234567890'); // "1234...7890"
inTenMinutes(); // string epoch timestamp 10 minutes from Date.now()

// core series
sAdd('1.01', '1.02'); // "2.03"
sSub('5', '2'); // "3"
sMul('2.5', '1.5'); // "3.75"
sDiv('6', '2'); // "3"
sAddRay('1', '2', '3'); // "6"

// underscore series adds Solidity boundary checking & reporting
_Add('1.5', '2.3'); // "3.8"
_Sub('5', '2'); // "3"
_Mul('2.5', '1.5'); // "3.75"
_Div('6', '2'); // "3"
_AddRay('1', '2', '3'); // "6"
//_Chk - checks a number for solidity boundary violations
_Chk('12345.12345') // "12345.12345"
_Chk('-12345.12345') // throws math underflow warning
_Chk(sAdd(sUint256max,'1')) // throws math overflow warning

// eccentric series
sRnd('1.23456', -2); // "1.23" //TODO: expand explanation
sAbs('-7.89'); // "7.89"
sPow('2', '3'); // "8"
//sFla: "formula" same as exactMath.formula() with config matching rest of zmath
sFla('2e+3'); // "2000"
//sFlr: "floor" 
sFlr('1.23456', -3) // 
_Flr('1.23456') //1 (solidity 
//sExp (expand x by y^10) moves decimal left or right 
// TODO: perhaps rename to sDec
// "expand 10 negatively by 2 powers of 10" 
sExp('10', '-2'); // "0.1"
// "expand 10 positively by 2 powers of 10" 
sExp('10', '2'); // "1000"

// "hr" shorthand denotes "human readable" formatting
sHR('1234567890.123456'); // "1_234_567_890.1234"
sExpHR('1234567890.123456', 3); // "1_234_567_890.123"
sNewtonSqRt('25'); // "5"

// comparator series
sIs('5', '>', '3'); // true
sIs0('0'); // true
sIsGT('5', '3'); // true
sIsLT('2', '4'); // true
sIsGTorEq('5', '5'); // true
sIsLTorEq('3', '3'); // true
sIsEq('7', '7'); // true
sIsNotEq('6', '7'); // true

// change series - track change between values
sChg('10', '15'); // "-5"
sChg.ba('10', '15'); // { before: "10", after: "15", change: "5" }
sChg.hr('10', '15', 2); // "5.00"
sChg.pct('10', '15'); // "+50%"
sChg.pct('10', '5'); // "-50%"
sChg.bahr('10', '15', 2); // { before: "10.00 (10)", after: "15.00 (15)", change: "5.00 (5)", changePct: "+50%" }
sChg.full('10', '15', 2); // { before: "10.00 (10)", after: "15.00 (15)", change: "5.00 (5)", changePct: "+50%" }

// color utils
lightenDarkenColor('#00F', 10); // "#a0a190"
lightenDarkenColor('00F', 10); // "a0a190"

TODOs:

v1 patches

  • new utilities for BigNumber, BigInt, and Hex
  • existing function support for BigInt
  • add jsdoc and/or typescript for all functions
  • expand color operations support
  • support more uniswap router operations Eg. getAmountOut et al
  • support chaining of operations

for 2.0

  • rethink some naming conventions