Formatter constructor
The constructor takes a list of numbers
. It is best to provide
all the numbers that will be represented alongside each other,
or at least a good sample of them.
Implementation
Formatter(List<double> numbers) {
assert(
numbers.length >= 2,
'You should provide at least two numbers '
'to the formatter. Otherwise it might emit weirdly unspecific'
'numbers.');
// The default is the Dart automatic precision.
var best = _Precision(
'324.34143423',
(n) => n.toString(),
);
var largestValue = numbers.fold<double>(0, (prev, e) => max(prev, e.abs()));
final representations = <String>{};
// For each precision, in order of "vagueness" ...
for (final precision in _precisions) {
var cumulativeError = 0.0;
representations.clear();
for (final n in numbers) {
if (!n.isFinite) continue;
// ... try the precision on each number ...
final r = precision.formatFunction(n);
if (representations.contains(r)) break;
representations.add(r);
cumulativeError += (n - precision.parseBack(r)).abs();
}
// ... discard the ones that accrue too large of an error ...
if (cumulativeError > 0.05 * largestValue) {
// (0.05 is an arbitrary constant. It _feels_ weird when the cumulative
// error is more than 5% of the largest value in the set.)
continue;
}
// ... and see if it results in a set of unique representations.
if (representations.length == numbers.length) {
best = precision;
// No need to continue, we've found our precision.
break;
}
}
_precision = best;
}