toDecimalString method

String toDecimalString(
  1. int decimalPlaces, {
  2. RoundingMode mode = RoundingMode.halfUp,
  3. bool stripTrailingZeros = false,
  4. String? locale,
  5. String? pattern,
})

Formats the rational number as a localized decimal string with a specified number of decimal places, applying the given rounding mode

Note: This method converts the Rational to double for formatting via the intl package. For values requiring more than ~15 significant digits, precision may be lost in display. The Rational value itself remains exact; only the formatted output is affected.

Example:

import 'package:numeric_utils/extensions/numeric_extensions.dart';
import 'package:rational/rational.dart';

final rational = Rational.fromInt(1, 3);                                   // i.e., Rational.parse('1/3');
print(rational.toDecimalString(3, locale: 'en_US'));                             // Output: 0.333
print(rational.toDecimalString(3, mode: RoundingMode.up, locale: 'fr_FR'));     // Output: 0,334

final quarter = Rational.fromInt(1, 4);                                    // i.e., Rational.parse('1/4');
print(quarter.toDecimalString(3, locale: 'de_DE'));                              // Output: 0,250
print(quarter.toDecimalString(3, stripTrailingZeros: true, locale: 'de_DE'));   // Output: 0,25

// Using a custom pattern to show percentage with 2 decimal places
final percentage = Rational.fromInt(75, 100)                               // i.e., Rational.parse('75/100');
print(percentage.toDecimalString(2, pattern: '#.00%', locale: 'en_US'));         // Output: 75.00%

// Using a custom pattern to show currency
final price = Rational.fromInt(1999, 100)                                  // i.e., Rational.parse('1999/100');
print(price.toDecimalString(2, pattern: 'ยค#,##0.00', locale: 'en_US'));          // Output: $19.99

Parameters:

  • decimalPlaces: The number of decimal places to include in the formatted string
  • mode: The rounding mode to apply when truncating or rounding the number. Defaults to RoundingMode.halfUp
  • stripTrailingZeros: If true, trailing zeros after the decimal point are removed. Defaults to false
  • locale: The locale to use for formatting the number. Defaults to the system's default locale
  • pattern: Optional custom number pattern to use for formatting. If not provided, uses the locale's decimal pattern

Returns: A localized string representation of the rational number with the specified decimal places and rounding

Throws:

  • ArgumentError: If decimalPlaces is negative
  • FormatException: If the number cannot be parsed or formatted

Implementation

String toDecimalString(
  int decimalPlaces, {
  RoundingMode mode = RoundingMode.halfUp,
  bool stripTrailingZeros = false,
  String? locale,
  String? pattern,
}) {
  if (decimalPlaces < 0) {
    throw ArgumentError('The number of decimal places must be non-negative.');
  }

  // Scale and round the number
  final scale = BigInt.from(10).pow(decimalPlaces);
  final scaled = (this * Rational(scale)).rounded(mode);
  final result = scaled / Rational(scale);

  try {
    // Create number format based on locale and/or pattern
    final numberFormat = pattern != null ? NumberFormat(pattern, locale) : NumberFormat.decimalPattern(locale);

    // Configure decimal places
    numberFormat.minimumFractionDigits = stripTrailingZeros ? 0 : decimalPlaces;
    numberFormat.maximumFractionDigits = decimalPlaces;

    // Return the formatted number
    return numberFormat.format(result.toDouble());
  } on FormatException catch (e) {
    throw FormatException('Failed to format number: ${e.message}', e.source, e.offset);
  }
}