Dart - 数字格式化

32
NumberFormat是否有一种方法可以显示以下内容:

  • 如果double值为15.00,则显示'15'
  • 如果double值为15.50,则显示'15.50'

谢谢您的帮助。

8个回答

75

实际上,我认为使用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

5
好的,我会尽力为您进行翻译:我不得不对此发笑,因为这种语言声称喜欢简洁。 - fostandy
太棒了,+1 远远不够。 - Suyon Won
5
并不是每种情况都适用。比如如果有一个值为 n1=15.0001,那么结果字符串将会是 15.00。像 return n.toStringAsFixed(2).endsWith('.00') ? n.toStringAsFixed(0) : n.toStringAsFixed(2); 这样的代码可以实现,但可能有点啰嗦。 - Jorge Bonafé
甚至可以这样写 myToStringAsFixed(double d, {int n=1,}){ return (d.toStringAsFixed(n).endsWith('.000000000000'.substring(0,n))) ? d.toStringAsFixed(n) : d.toStringAsFixed(n); } - Chris Nadovich

6

编辑: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;
}

9
我不确定为什么没有人提到这是一个外部包,如果你需要使用它。 - Tokenyet

4

不太容易。如果您想将整数值打印为零小数位,并且将浮点数打印为精确的两位小数,您可以这样做:

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并没有多大优势。


1
也许您不想使用NumberFormat:
class DoubleToString {
  String format(double toFormat) {
    return (toFormat * 10) % 10 != 0 ?
      '$toFormat' :
      '${toFormat.toInt()}';
  }
}

0

这里有一个灵活的函数,可以很好地四舍五入并删除小数点后面的尾随零,以解决双精度浮点数的不完美问题。这个函数不能处理严格的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

0

双精度浮点数格式的一种变体:

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';
}

0

另一种解决方案,针对NumberFormat的字符串输出进行操作:

final f = NumberFormat("###.00");
print(f.format(15.01).replaceAll('.00', ''));
print(f.format(15.00).replaceAll('.00', ''));

发布前没有仔细检查代码?“错误:期望2个位置参数,但只找到1个(not_enough_positional_arguments)”。更不用提缺少i18n的问题了。 - Anton Duzenko
@AntonDuzenko 感谢你指出这个错误。拼写错误已经纠正了。如果你愿意,可以继续改进并添加国际化支持。 - Ber
NumberFormat("##0.00", "en_US") - Anton Duzenko

0

这将会起作用。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接