Skip to content

Instantly share code, notes, and snippets.

@johnathanesanders
Last active August 5, 2020 12:39
Show Gist options
  • Save johnathanesanders/6ff43af233a964598083f787ee1df417 to your computer and use it in GitHub Desktop.
Save johnathanesanders/6ff43af233a964598083f787ee1df417 to your computer and use it in GitHub Desktop.
An asynchronous utility method for calculating percentages to a given precision
/**
*
* Asynchronously calculate a percentage to a given precision.
* @example
* const denominator: number = 435;
* const numberator: number = 37;
* const precision: number = 2;
* const percentage: number = await calculatePercentage(denominator, numerator, precision);
* console.log(`${numerator} is ${percentage} percent of ${denominator} to a precision of ${precision}`);
* @param {string|number} denominator - The value that the percentage will modify.
* @param {string|number} numerator - The result of the percentage operating on the denominator .
* @param {number} [precision=2] - The precision by which to calculate the percentage, which is the number of decimal places.
* @returns {Promise<number>} Thenable/Awaitable percentage
*/
export const calculatePercentage = async (denominator: string | number, numerator: string | number, precision: number = 2): Promise<number> => {
try {
// Copy parameters to temp parameters so that we can pass them back as they were sent to us in any applicable error message - such as before they are converted to floats or ints
const __numerator: any = numerator;
const __denominator: any = denominator;
const __precision: any = precision;
let percentage: number;
numerator = numerator ? (typeof numerator === 'string' ? parseFloat(numerator) : numerator) : 0;
denominator = denominator ? (typeof denominator === 'string' ? parseFloat(denominator) : denominator) : 0;
if (isNaN(numerator) || isNaN(denominator) || isNaN(precision)) throw ({code: 'NOTANUMBER', debug: {numerator: __numerator, numeratorType: typeof __numerator, denominator: __denominator, denominatorType: typeof __denominator, precision: __precision, precisionType: typeof __precision}, message: 'One or more parameters was not a number'});
if (numerator === denominator) {
percentage = 0;
} else {
percentage = parseFloat(((denominator / numerator) * 100).toPrecision(precision));
}
if (percentage === Infinity || percentage === -Infinity) {
percentage = 0;
}
if (isNaN(percentage)) throw ({code: 'NOTANUMBER', debug: {percentage: percentage, percentageType: typeof percentage}, message: 'Percentage value calculated to not a number'});
return Promise.resolve(percentage);
} catch (error) {
return Promise.reject(error);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment