std/number_format
import std/number_format to use it. Source: src/std/number_format.iyi at v0.18.0.
import std/number_format::{BinaryPrefixFormat} 1234567.format # => "1,234,567"
1234.5678.format(decimal_places: 2) # => "1,234.57"
1234.5.format(',', '.') # => "1.234,5"
1_234_567.humanize # => "1.23M"
0.000_012.humanize # => "12µ"
1536.humanize_bytes # => "1.5KiB"
1536.humanize_bytes(format: BinaryPrefixFormat::JEDEC) # => "1.5KB"**Exact.** Every rounding is of the value the number holds, half to even, on std/format's bignum: 1.005.format(decimal_places: 2) is "1.00", because the double is 1.00499999999999989..., and 2.5 rounds to "2". A float with no places asked for prints its shortest digits, the ones to_s prints, written out in full: 1e20.format is "100,000,000,000,000,000,000.0". A number that prints as zero carries no sign. NaN and the infinities print as to_s prints them.
**humanize** keeps precision significant digits by default and trims the zeros after them: 1000 is "1k", 1234 "1.23k", 999,999 "1M". With significant: false precision is the places after the point, kept as written. The SI prefixes run from q (10^-30) to Q (10^30); past them the digits grow, grouped: 1e40 is "10,000,000,000Q".
**humanize_bytes** divides by 1024: IEC's KiB, MiB, ... EiB by default, JEDEC's KB, MB, ... EB on request. Under 1024 a count is whole bytes, "1023B".
Two differences from the other library's methods of these names: IEC's kilo is written KiB, as IEC 80000-13 writes it, where the other library writes kiB; and the trimmed zeros take the point with them, "1k" where it writes "1.0k".
What each refuses, by panic: a group under 1, negative decimal places, a precision under 1 significant digit or under 0 places.
BinaryPrefixFormatenum
Which binary prefixes humanize_bytes writes.
pub enum BinaryPrefixFormat : Int32
IEC = 0
JEDEC = 1
endIntstruct, reopened
struct ::Int
# A count of bytes scaled by powers of 1024, as `humanize` scales by
# 1000.
def humanize_bytes(precision : Int32 = 3, separator : ::Char = '.', *, significant : ::Bool = true, unit_separator : ::String = "", format : Std::NumberFormat::BinaryPrefixFormat = Std::NumberFormat::BinaryPrefixFormat::IEC) : ::String
endNumberstruct, reopened
struct ::Number
# The number with its integer digits in groups of *group*, *delimiter*
# between them and *separator* before the fraction. *decimal_places*
# rounds to that many places, half to even; nil keeps an integer whole
# and a float's shortest digits. *only_significant* drops the fraction's
# trailing zeros, and the separator if nothing is left.
def format(separator : ::Char = '.', delimiter : ::Char = ',', decimal_places : Int32 | ::Nil = nil, *, group : Int32 = 3, only_significant : ::Bool = false) : ::String
# The number scaled to an SI prefix, with *precision* significant
# digits (or, with `significant: false`, places), *unit_separator*
# between it and the prefix.
def humanize(precision : Int32 = 3, separator : ::Char = '.', delimiter : ::Char = ',', *, significant : ::Bool = true, unit_separator : ::String = "") : ::String
end
Numbers as people read them: digits in groups, and quantities with a prefix.