【发布时间】:2017-02-18 21:16:55
【问题描述】:
有没有办法用NumberFormat 显示:
- '15' 如果双精度值是 15.00
- '15.50' 如果双精度值是 15.50
感谢您的帮助。
【问题讨论】:
有没有办法用NumberFormat 显示:
感谢您的帮助。
【问题讨论】:
实际上,我认为使用truncateToDouble() 和toStringAsFixed() 而不使用NumberFormat 更容易:
n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 2);
例如:
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);
}
打印到控制台:
15
15.50
【讨论】:
n1 = 15.0001,则结果字符串将为15.00。像return n.toStringAsFixed(2).endsWith('.00') ? n.toStringAsFixed(0) : n.toStringAsFixed(2); 这样的东西会起作用,但可能有点冗长。
编辑: Martin 发布的解决方案看起来更好
我认为这不能直接完成。你很可能需要这样的东西:
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;
}
【讨论】:
不是很容易。如果它是一个整数值,则解释你想要打印零小数位,如果它是一个浮点数则精确到两个,你可以这样做
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));
但使用 NumberFormat 并没有什么优势,除非您希望不同区域设置的打印结果不同。
【讨论】:
双值格式的变体:
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';
}
【讨论】:
也许你不想使用 NumberFormat:
class DoubleToString {
String format(double toFormat) {
return (toFormat * 10) % 10 != 0 ?
'$toFormat' :
'${toFormat.toInt()}';
}
}
【讨论】:
这会起作用。
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();
}
输出:
15
15.5
【讨论】:
另一种解决方案,处理 NumberFormat 的字符串输出:
final f = NumberFormat("###.00");
print(f.format(15.01).replaceAll('.00', ''));
print(f.format(15.00).replaceAll('.00', ''));
【讨论】:
error: 2 positional argument(s) expected, but 1 found. (not_enough_positional_arguments 。更不用说缺少 i18n
NumberFormat("##0.00", "en_US")
这是一个灵活的函数,可以很好地舍入并删除小数点后的尾随零,以解决 double 的缺陷。这不处理问题中严格的 0 或 2 个小数点情况,而是一种更通用的双数格式,可能对其他人有用。
verbose 值可以更改以满足精度需求。
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;
}
打印输出:
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
【讨论】: