const bitBase = 8;
const suffixes = {
bit: 'b',
b: 'B',
kb: 'KB',
mb: 'MB',
gb: 'GB',
tb: 'TB',
};
const multipliers = {
bit: {
toBitHr: 1,
toB: 1 / bitBase,
toKB: 1 / (bitBase * 1e3),
toMB: 1 / (bitBase * 1e6),
toGB: 1 / (bitBase * 1e9),
toTB: 1 / (bitBase * 1e12),
},
B: {
toBit: bitBase,
toBHr: 1,
toKB: 1 / 1e3,
toMB: 1 / 1e6,
toGB: 1 / 1e9,
toTB: 1 / 1e12,
},
KB: {
toBit: 1 / (bitBase * 1e3),
toB: 1e3,
toKBHr: 1,
toMB: 1 / 1e3,
toGB: 1 / 1e6,
toTB: 1 / 1e9,
},
MB: {
toBit: bitBase * 1e6,
toB: 1e6,
toKB: 1e3,
toMBHr: 1,
toGB: 1 / 1e3,
toTB: 1 / 1e6,
},
GB: {
toBit: bitBase * 1e9,
toB: 1e9,
toKB: 1e6,
toMB: 1e3,
toGBHr: 1,
toTB: 1 / 1e3,
},
TB: {
toBit: bitBase * 1e12,
toB: 1e12,
toKB: 1e9,
toMB: 1e6,
toGB: 1e3,
toTBHr: 1,
},
};
const round = (num, decimalPlaces) => {
const strNum = num.toString();
const isExp = strNum.includes('e');
if (isExp) {
return Number(num.toPrecision(decimalPlaces + 1));
}
return Number(
`${Math.round(Number(`${num}e${decimalPlaces}`))}e${decimalPlaces * -1}`,
);
};
function conv(
value,
hr,
rnd,
multiplier,
suffix,
) {
let val = value * multiplier;
if ((value * multiplier) > Number.MAX_SAFE_INTEGER) {
val = Number.MAX_SAFE_INTEGER;
}
if (val < Number.MIN_VALUE) val = 0;
if ((rnd || rnd === 0) && val < Number.MAX_SAFE_INTEGER) {
val = round(val, rnd);
}
if (hr) return `${val}${suffix}`;
return val;
}
const MemConv = (function _() {
return {
bit(value) {
return {
toBitHr(opts = {}) {
return conv(
value,
true,
opts.round || false,
multipliers.bit.toBitHr,
suffixes.bit,
);
},
toB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.bit.toB,
suffixes.b,
);
},
toKB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.bit.toKB,
suffixes.kb,
);
},
toMB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.bit.toMB,
suffixes.mb,
);
},
toGB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.bit.toGB,
suffixes.gb,
);
},
toTB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.bit.toTB,
suffixes.tb,
);
},
};
},
B(value) {
return {
toBit(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.B.toBit,
suffixes.bit,
);
},
toBHr(opts = {}) {
return conv(
value,
true,
opts.round || false,
multipliers.B.toBHr,
suffixes.b,
);
},
toKB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.B.toKB,
suffixes.kb,
);
},
toMB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.B.toMB,
suffixes.mb,
);
},
toGB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.B.toGB,
suffixes.gb,
);
},
toTB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.B.toTB,
suffixes.tb,
);
},
};
},
KB(value) {
return {
toBit(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.KB.toBit,
suffixes.bit,
);
},
toB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.KB.toB,
suffixes.b,
);
},
toKBHr(opts = {}) {
return conv(
value,
true,
opts.round || false,
multipliers.KB.toKBHr,
suffixes.kb,
);
},
toMB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.KB.toMB,
suffixes.mb,
);
},
toGB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.KB.toGB,
suffixes.gb,
);
},
toTB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.KB.toTB,
suffixes.tb,
);
},
};
},
MB(value) {
return {
toBit(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.MB.toBit,
suffixes.bit,
);
},
toB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.MB.toB,
suffixes.b,
);
},
toKB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.MB.toKB,
suffixes.kb,
);
},
toMBHr(opts = {}) {
return conv(
value,
true,
opts.round || false,
multipliers.MB.toMBHr,
suffixes.mb,
);
},
toGB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.MB.toGB,
suffixes.gb,
);
},
toTB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.MB.toTB,
suffixes.tb,
);
},
};
},
GB(value) {
return {
toBit(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.GB.toBit,
suffixes.bit,
);
},
toB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.GB.toB,
suffixes.b,
);
},
toKB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.GB.toKB,
suffixes.kb,
);
},
toMB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.GB.toMB,
suffixes.mb,
);
},
toGBHr(opts = {}) {
return conv(
value,
true,
opts.round || false,
multipliers.GB.toGBHr,
suffixes.gb,
);
},
toTB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.GB.toTB,
suffixes.tb,
);
},
};
},
TB(value) {
return {
toBit(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.TB.toBit,
suffixes.bit,
);
},
toB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.TB.toB,
suffixes.b,
);
},
toKB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.TB.toKB,
suffixes.kb,
);
},
toMB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.TB.toMB,
suffixes.mb,
);
},
toGB(opts = {}) {
return conv(
value,
opts.hr || false,
opts.round || false,
multipliers.TB.toGB,
suffixes.gb,
);
},
toTBHr(opts = {}) {
return conv(
value,
true,
opts.round || false,
multipliers.TB.toTBHr,
suffixes.tb,
);
},
};
},
};
}());
const testCases = [1, 10, 150, 1000, 74839.67346];
const HRSuffixes = Object.values(suffixes);
const roundDecimals = 2;
const precision = Number(`0.${'0'.repeat(roundDecimals)}5`);
const SCIENTIFIC_NOT_NUMBER_REGXP = /[-+]?[0-9]*.?[0-9]+([eE][-+]?[0-9]+)?/g;
const SUFFIX_REGXP = /[a-z]+$/i;
const CONVERSION_TO_REGXP = /(?<=to).*(?=hr+$)|(?<=to).*(?=hr+$)?/i;
for (const conversionFrom of (Object.keys(MemConv))) {
for (const tCase of testCases) {
const convFunc = MemConv[conversionFrom](tCase);
for (const [conversionToFn, f] of Object.entries(convFunc)) {
const conversionTo = (conversionToFn.match(CONVERSION_TO_REGXP) || [conversionToFn])[0];
const result = f();
const humanReadable = f({ hr: true });
const rounded = f({ round: roundDecimals });
const roundedAndHumanReadable = f({ hr: true, round: roundDecimals });
console.log({
value: tCase,
from: conversionFrom,
to: conversionTo,
result,
humanReadable,
rounded,
roundedAndHumanReadable,
});
}
}
}
1.445281982421875
which correctly rounds down to 1.4. – ShandrashandrydanYB
. Doubtful anyone will get even 1 YB for his DB. It will cost 100 trillion dollars! – Albin