d4_format library
Format numbers for human consumption.
Ever noticed how sometimes Dart doesn’t display numbers the way you expect? Like, you tried to print tenths with a simple loop:
for (var i = 0; i < 10; ++i) {
print(0.1 * i);
}
And you got this:
0
0.1
0.2
0.30000000000000004
0.4
0.5
0.6000000000000001
0.7000000000000001
0.8
0.9
Welcome to binary floating point! ಠ_ಠ
Yet rounding error is not the only reason to customize number formatting. A table of numbers should be formatted consistently for comparison; above, 0.0 would be better than 0. Large numbers should have grouped digits (e.g., 42,000) or be in scientific or metric notation (4.2e+4, 42k). Currencies should have fixed precision ($3.50). Reported numerical results should be rounded to significant digits (4021 becomes 4000). Number formats should appropriate to the reader’s locale (42.000,00 or 42,000.00). The list goes on.
Formatting numbers for human consumption is the purpose of d4+format, which is modeled after Python 3’s format specification mini-language (PEP 3101). Revisiting the example above:
final f = format(".1f");
for (var i = 0; i < 10; ++i) {
print(f(0.1 * i));
}
Now you get this:
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
But d4_format is much more than an alias for num.toStringAsFixed! A few more examples:
format(".0%")(0.123); // rounded percentage, "12%"
format("(\$.2f")(-3.5); // localized fixed-point currency, "(£3.50)"
format("+20")(42); // space-filled and signed, " +42"
format(".^20")(42); // dot-filled and centered, ".........42........."
format(".2s")(42e6); // SI-prefix with two significant digits, "42M"
format("#x")(48879); // prefixed lowercase hexadecimal, "0xbeef"
format(",.2r")(4223); // grouped thousands with two significant digits, "4,200"
See FormatLocale.format for a detailed specification, and try running FormatSpecifier.parse on the above formats to decode their meaning.
Classes
- FormatLocale
- Locale formats define how a value should be formatted in a locale-specific way.
- FormatSpecifier
- Format specifiers define how a number should be formatted (see FormatLocale.format) and can be created and derived in a structured way.
Functions
-
format(
String specifier) → String Function(Object?) - An alias for FormatLocale.format on the default locale (see formatDefaultLocale).
-
formatDefaultLocale(
{String? decimal, String? thousands, List< int> ? grouping, List<String> ? currency, List<String> ? numerals, String? percent, String? minus, String? nan}) → FormatLocale - Equivalent to FormatLocale.new, except it also redefines format and formatPrefix to the new locale’s FormatLocale.format and FormatLocale.formatPrefix.
-
formatDefaultLocaleFromJson(
Map< String, dynamic> definition) → FormatLocale -
Equivalent to formatDefaultLocale, but it accepts a JSON
definition
object instead of individual arguments. -
formatPrefix(
String specifier, num value) → String Function(num) - An alias for FormatLocale.formatPrefix on the default locale (see formatDefaultLocale).
-
precisionFixed(
num step) → num -
Returns a suggested decimal precision for fixed point notation given the
specified numeric
step
value. -
precisionPrefix(
num step, num value) → num -
Returns a suggested decimal precision for use with
FormatLocale.formatPrefix given the specified numeric step and reference
value
. -
precisionRound(
num step, num max) → num -
Returns a suggested decimal precision for format types that round to
significant digits given the specified numeric
step
andmax
values.