const UNITS = ['','K','M','G','T','P']; const FRACTIONAL = ['','m','u','n','p','f']; // milli micro nano pico femto export function formatSi(inValue, increment=1000, suffix=null, firstSuffix=null, startingExponent=0, minExponent=0) { var val = inValue; var exp = startingExponent; while ( val >= increment && exp+1 < UNITS.length || exp < minExponent ) { val = val/increment; exp++; } var out = ''; if ( (val < 1) || ( val < 10 ) ) { out = Math.round(val*100)/100; } else if ( val < 100 ) { out = Math.round(val*10)/10; } else { out = Math.round(val); } if ( exp === 0 && firstSuffix !== null) { out += " " + firstSuffix; } else { out += " " + UNITS[exp] + suffix||''; } return out; } export function exponentNeeded(val, increment=1000) { let exp = 0; while ( val >= increment ) { val = val/increment; exp++; } return exp; } export function parseSi(inValue, increment=null, allowFractional=true) { if ( !inValue || typeof inValue !== 'string' || !inValue.length ) { return NaN; } inValue = inValue.replace(/,/g,'') let [, valStr, unit, incStr] = inValue.match(/^([0-9.-]+)\s*([^0-9.-]?)([^0-9.-]?)/); const val = parseFloat(valStr); if ( !unit ) { return val; } // micro "mu" symbol -> u if ( unit.charCodeAt(0) === 181 ) { unit = 'u'; } const divide = FRACTIONAL.includes(unit); const multiply = UNITS.includes(unit.toUpperCase()); if ( increment === null ) { // Automatically handle 1 KB = 1000B, 1 KiB = 1024B if no increment set if ( (multiply || divide) && incStr === 'i' ) { increment = 1024; } else { increment = 1000; } } if ( divide && allowFractional ) { const exp = FRACTIONAL.indexOf(unit); return val / Math.pow(increment, exp); } if ( multiply ) { const exp = UNITS.indexOf(unit.toUpperCase()); return val * Math.pow(increment, exp); } // Unrecognized unit character return val; }