formatNumberLocale function

String formatNumberLocale(
  1. num value, {
  2. int decimalPlaces = 0,
  3. String groupSep = ',',
})

Formats number with decimalPlaces and optional groupSep (e.g. ','). Audited: 2026-06-12 11:26 EDT

Implementation

String formatNumberLocale(
  num value, {
  int decimalPlaces = 0,
  String groupSep = ',',
}) {
  // Render the number first (rounded int, or fixed decimals), then insert group
  // separators into the integer part only.
  final String raw = decimalPlaces <= 0
      ? value.round().toString()
      // Clamp to 20: toStringAsFixed throws a RangeError above 20 fraction
      // digits, so an oversized decimalPlaces would crash instead of formatting.
      // formatDouble in double_extensions clamps to the same ceiling.
      : value.toStringAsFixed(decimalPlaces.clamp(1, 20));
  if (groupSep.isEmpty) return raw;
  final List<String> parts = raw.split('.');
  final String intPart = parts[0];
  // Peel a leading sign off before grouping so it does not get a separator.
  final String sign = intPart.startsWith('-') ? '-' : '';
  final String digits = sign.isEmpty ? intPart : intPart.substringSafe(1);
  final StringBuffer sb = StringBuffer(sign);
  // Emit a separator every 3 digits counting from the RIGHT (the distance from
  // the end is a multiple of 3), so grouping aligns to thousands regardless of length.
  for (int i = 0; i < digits.length; i++) {
    if (i > 0 && (digits.length - i) % 3 == 0) sb.write(groupSep);
    sb.write(digits[i]);
  }
  if (parts.length > 1) {
    sb
      ..write('.')
      ..write(parts[1]);
  }
  return sb.toString();
}