diff --git a/index.d.ts b/index.d.ts index 9a64626..681287b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -20,9 +20,9 @@ declare namespace prettyBytes { /** Format the number as [bits](https://en.wikipedia.org/wiki/Bit) instead of [bytes](https://en.wikipedia.org/wiki/Byte). This can be useful when, for example, referring to [bit rate](https://en.wikipedia.org/wiki/Bit_rate). - + @default false - + ``` import prettyBytes = require('pretty-bytes'); @@ -31,6 +31,23 @@ declare namespace prettyBytes { ``` */ readonly bits?: boolean; + + /** + Format the number using the [Binary Prefix](https://en.wikipedia.org/wiki/Binary_prefix) instead of the [SI Prefix](https://en.wikipedia.org/wiki/SI_Prefix). This can be useful for presenting memory amounts. However, this should not be used for presenting file sizes. + + @default false + + ``` + import prettyBytes = require('pretty-bytes'); + + prettyBytes(1000, {binary: true}); + //=> '1000 bit' + + prettyBytes(1024, {binary: true}); + //=> '1 kiB' + ``` + */ + readonly binary?: boolean; } } diff --git a/index.js b/index.js index b7a0bac..d88fd8b 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,18 @@ const BYTE_UNITS = [ 'YB' ]; +const BIBYTE_UNITS = [ + 'B', + 'kiB', + 'MiB', + 'GiB', + 'TiB', + 'PiB', + 'EiB', + 'ZiB', + 'YiB' +]; + const BIT_UNITS = [ 'b', 'kbit', @@ -46,8 +58,8 @@ module.exports = (number, options) => { throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`); } - options = Object.assign({bits: false}, options); - const UNITS = options.bits ? BIT_UNITS : BYTE_UNITS; + options = Object.assign({bits: false, binary: false}, options); + const UNITS = options.bits ? (options.binary ? BIBYTE_UNITS : BIT_UNITS) : BYTE_UNITS; if (options.signed && number === 0) { return ' 0 ' + UNITS[0]; @@ -65,9 +77,9 @@ module.exports = (number, options) => { return prefix + numberString + ' ' + UNITS[0]; } - const exponent = Math.min(Math.floor(Math.log10(number) / 3), UNITS.length - 1); + const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1); // eslint-disable-next-line unicorn/prefer-exponentiation-operator - number = Number((number / Math.pow(1000, exponent)).toPrecision(3)); + number = Number((number / Math.pow(options.binary ? 1024 : 1000, exponent)).toPrecision(3)); const numberString = toLocaleString(number, options.locale); const unit = UNITS[exponent]; diff --git a/index.test-d.ts b/index.test-d.ts index cfbd1c9..f7c94a7 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -8,3 +8,4 @@ expectType(prettyBytes(42, {signed: true})); expectType(prettyBytes(1337, {locale: 'de'})); expectType(prettyBytes(1337, {locale: true})); expectType(prettyBytes(1337, {bits: true})); +expectType(prettyBytes(1337, {binary: true})); diff --git a/readme.md b/readme.md index ea10506..717377a 100644 --- a/readme.md +++ b/readme.md @@ -68,6 +68,13 @@ Default: `false` Format the number as [bits](https://en.wikipedia.org/wiki/Bit) instead of [bytes](https://en.wikipedia.org/wiki/Byte). This can be useful when, for example, referring to [bit rate](https://en.wikipedia.org/wiki/Bit_rate). +##### binary + +Type: `boolean`\ +Default: `false` + +Format the number using the [Binary Prefix](https://en.wikipedia.org/wiki/Binary_prefix) instead of the [SI Prefix](https://en.wikipedia.org/wiki/SI_Prefix). This can be useful for presenting memory amounts. However, this should not be used for presenting file sizes. + ##### locale Type: `boolean | string`\ diff --git a/test.js b/test.js index 2753d54..ff61e77 100644 --- a/test.js +++ b/test.js @@ -82,3 +82,15 @@ test('bits option', t => { t.is(prettyBytes(1e16, {bits: true}), '10 Pbit'); t.is(prettyBytes(1e30, {bits: true}), '1000000 Ybit'); }); + +test('binary option', t => { + t.is(prettyBytes(0, {binary: true}), '0 B'); + t.is(prettyBytes(4, {binary: true}), '4 B'); + t.is(prettyBytes(10, {binary: true}), '10 B'); + t.is(prettyBytes(10.1, {binary: true}), '10.1 B'); + t.is(prettyBytes(999, {binary: true}), '999 B'); + t.is(prettyBytes(1025, {binary: true}), '1 kB'); + t.is(prettyBytes(1001, {binary: true}), '1000 B'); + t.is(prettyBytes(1e16, {binary: true}), '8.88 PB'); + t.is(prettyBytes(1e30, {binary: true}), '827000 YB'); +});