E-notation for certain inputs when precision is 1 or 2
betamos opened this issue · 4 comments
If the number cannot be represented with the desired precision, we get scientific ("e-") notation:
[1, 2, 3].map(p => filesize(1234567, {precision: p})) // ["1 MB", "1.2 MB", "1.23 MB"]
[1, 2, 3].map(p => filesize(12345678, {precision: p})) // ["1e+1 MB", "12 MB", "12.3 MB"]
[1, 2, 3].map(p => filesize(123456789, {precision: p})) // ["1e+2 MB", "1.2e+2 MB", "123 MB"]
I'd expect an integer even if it contains more digits than the desired precision:
[1, 2, 3].map(p => filesize(1234567, {precision: p})) // ["1 MB", "1.2 MB", "1.23 MB"]
[1, 2, 3].map(p => filesize(12345678, {precision: p})) // ["12 MB", "12 MB", "12.3 MB"]
[1, 2, 3].map(p => filesize(123456789, {precision: p})) // ["123 MB", "123 MB", "123 MB"]
My usecase for a lower precision is to reduce visual clutter in large tables. E.g. in macOS Finder, I see "816 bytes" and "2 kB" in the same column.
@betamos that's based on the spec for toPrecision()
and not implemented by filesize()
beyond executing the method on the number.
// note that exponential notation might be returned in some circumstances
console.log((1234.5).toPrecision(2)) // logs '1.2e+3'
To clarify lets use the middle* number of 12.35 MiB with a precision of 1 becomes 10 which then becomes scientific notation because... toFixed() i guess.
I've noticed most people misunderstand what precision means; it's not the decimal points and it's base 10.
(12.3).toPrecision(1) // 10 (1e+1)
(12.3).toPrecision(2) // 12
(12.3).toPrecision(3) // 12.3
So your expectation that 10
should be 12
doesn't make sense.
Here's a workaround:
function myFilesize(bytes, opts) {
const str = filesize(bytes, opts);
// Convert exponential notation to ordinary.
return str.replace(/[\d.]+e[+\d]+/, parseFloat);
}
console.log([1, 2, 3].map((p) => myFilesize(1234567, { precision: p }))); // ['1 MB', '1.2 MB', '1.23 MB']
console.log([1, 2, 3].map((p) => myFilesize(12345678, { precision: p }))); // ['10 MB', '12 MB', '12.3 MB']
console.log([1, 2, 3].map((p) => myFilesize(123456789, { precision: p }))); // ['100 MB', '120 MB', '123 MB']
This is what you're working around: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.prototype.toprecision
You could have more efficient code if you used the partial()
exported function to cache your opts
if you actually have code like that in irl.