Numbers written to fit a column: as given if they fit, with fewer
decimals if that does, else compactly, in thousands (k), millions
(M), billions (G), then T, P and E.
This port's own, for readings bigger than upstream's columns were made
for: a value of 3,020,463,651 in five cells is 3.02G rather than
30204, cut at the edge.
iex> Ascii.Kit.Number.fit(3_020_463_651, 0, 5)
"3.02G"
iex> Ascii.Kit.Number.fit(1234.5678, 2, 7)
"1234.57"
iex> Ascii.Kit.Number.fit(42, 1, 5)
"42.0"
Summary
Functions
x in thousands, millions and on, with as many decimals as width
leaves, trailing zeros dropped: 17.5M, -3.02G, 999k. A number too
long for width however it is written comes as short as it can be.
x in at most width characters: x.toFixed(digits) if it fits, else
with as many of those decimals as fit, else compact/2.
Numbers for one column or one line, each in at most width characters
and all alike: with as many of digits decimals as let every one fit;
else all in the unit of the largest, with as many decimals as fit but
for zeros they all end in; else each compact/2.
Functions
@spec compact(x :: number(), width :: pos_integer()) :: String.t()
x in thousands, millions and on, with as many decimals as width
leaves, trailing zeros dropped: 17.5M, -3.02G, 999k. A number too
long for width however it is written comes as short as it can be.
iex> Ascii.Kit.Number.compact(17_500_073, 5)
"17.5M"
iex> Ascii.Kit.Number.compact(-999_950, 4)
"-1M"
iex> Ascii.Kit.Number.compact(1_000_000, 7)
"1M"
@spec fit(x :: number(), digits :: non_neg_integer(), width :: pos_integer()) :: String.t()
x in at most width characters: x.toFixed(digits) if it fits, else
with as many of those decimals as fit, else compact/2.
@spec fit_all(xs :: [number()], digits :: non_neg_integer(), width :: pos_integer()) :: [String.t()]
Numbers for one column or one line, each in at most width characters
and all alike: with as many of digits decimals as let every one fit;
else all in the unit of the largest, with as many decimals as fit but
for zeros they all end in; else each compact/2.
iex> Ascii.Kit.Number.fit_all([9999.5, 10_000], 2, 7)
["9999.5", "10000.0"]
iex> Ascii.Kit.Number.fit_all([98_931_000, 98_930_000, 98_929_000], 2, 7)
["98.931M", "98.930M", "98.929M"]
iex> Ascii.Kit.Number.fit_all([18_000_000, 17_500_000], 2, 7)
["18.0M", "17.5M"]