Reputation: 3689
Is there a way with NumberFormat
to display :
Thanks for your help.
Upvotes: 39
Views: 59176
Reputation: 491
Here is a flexible function that nicely rounds and removes trailing zeros after the decimal point to resolve double's imperfections. This doesn't handle the strictly 0 or 2 decimal points scenario from the question, but rather is a more general formatting for double numbers that may be useful for others to consider.
The verbose
value can be changed to fit precision needs.
void main() {
for (double i = 0; i < 10; i += 0.3) {
print(i);
print(_formatDouble(i));
}
}
//Creates nicely formatted number string without trailing decimal zeros.
String _formatDouble(double value) {
//this also rounds (so 0.8999999999999999 becomes '0.9000')
var verbose = value.toStringAsFixed(4);
var trimmed = verbose;
//trim all trailing 0's after the decimal point (and the decimal point if applicable)
for (var i = verbose.length - 1; i > 0; i--) {
if (trimmed[i] != '0' && trimmed[i] != '.' || !trimmed.contains('.')) {
break;
}
trimmed = trimmed.substring(0, i);
}
return trimmed;
}
prints output:
0
0
0.3
0.3
0.6
0.6
0.8999999999999999
0.9
1.2
1.2
1.5
1.5
1.8
1.8
2.1
2.1
2.4
2.4
2.6999999999999997
2.7
2.9999999999999996
3
3.2999999999999994
3.3
3.599999999999999
3.6
3.899999999999999
3.9
4.199999999999999
4.2
4.499999999999999
4.5
4.799999999999999
4.8
5.099999999999999
5.1
5.399999999999999
5.4
5.699999999999998
5.7
5.999999999999998
6
6.299999999999998
6.3
6.599999999999998
6.6
6.899999999999998
6.9
7.1999999999999975
7.2
7.499999999999997
7.5
7.799999999999997
7.8
8.099999999999998
8.1
8.399999999999999
8.4
8.7
8.7
9
9
9.3
9.3
9.600000000000001
9.6
9.900000000000002
9.9
Upvotes: 0
Reputation: 41813
An alternate solution, working on the string output of NumberFormat:
final f = NumberFormat("###.00");
print(f.format(15.01).replaceAll('.00', ''));
print(f.format(15.00).replaceAll('.00', ''));
Upvotes: 0
Reputation: 1
This will work.
main() {
double n1 = 15.00;
double n2 = 15.50;
print(_formatDecimal(n1));
print(_formatDecimal(n2));
}
_formatDecimal(double value) {
if (value % 1 == 0) return value.toStringAsFixed(0).toString();
return value.toString();
}
Output:
15
15.5
Upvotes: 0
Reputation: 4849
Maybe you don't want use NumberFormat:
class DoubleToString {
String format(double toFormat) {
return (toFormat * 10) % 10 != 0 ?
'$toFormat' :
'${toFormat.toInt()}';
}
}
Upvotes: 1
Reputation: 960
A variant of double value formatting:
void main (){
final n1 = 15.00;
final n2 = 15.50;
print(format(n1));
print(format(n2));
}
String format(double n) {
final fraction = n - n.toInt();
if (fraction == 0.0) {
return n.toString();
}
var twoDigitFraction = (fraction * 100).truncateToDouble().toInt();
return '${n.toInt()}.$twoDigitFraction';
}
Upvotes: 0
Reputation: 2971
Not very easily. Interpreting what you want as printing zero decimal places if it's an integer value and precisely two if it's a float, you could do
var forInts = new NumberFormat();
var forFractions = new NumberFormat();
forFractions.minimumFractionDigits = 2;
forFractions.maximumFractionDigits = 2;
format(num n) =>
n == n.truncate() ? forInts.format(n) : forFractions.format(n);
print(format(15.50));
print(format(15.0));
But there's little advantage in using NumberFormat for this unless you want the result to print differently for different locales.
Upvotes: 4
Reputation: 1239
Edit: The solution posted by Martin seens to be a better one
I don't think this can be done directly. You'll most likely need something like this:
final f = new NumberFormat("###.00");
String format(num n) {
final s = f.format(n);
return s.endsWith('00') ? s.substring(0, s.length - 3) : s;
}
Upvotes: 7
Reputation: 96889
Actually, I think it's easier to go with truncateToDouble()
and toStringAsFixed()
and not use NumberFormat
at all:
n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
So for example:
main() {
double n1 = 15.00;
double n2 = 15.50;
print(format(n1));
print(format(n2));
}
String format(double n) {
return n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
}
Prints to console:
15
15.50
Upvotes: 81