toDecimal method

Decimal toDecimal({
  1. int? scale,
  2. RoundingMode? mode,
})

Implementation

Decimal toDecimal({int? scale, RoundingMode? mode}) {
  // Special handling for integer-valued doubles (e.g., 0.0, 1.0, 2.0)
  final isIntegerValued = this == truncateToDouble();

  // Convert double to string, then parse
  final str = this.toString();
  var parsed = Decimal.parse(str);

  // Remove trailing zeros but keep at least one decimal place for integer-valued doubles
  if (parsed._scale > 1) {
    var valueStr = parsed._value.abs().toString();
    var trailingZeros = 0;
    for (var i = valueStr.length - 1; i >= 0 && valueStr[i] == '0'; i--) {
      trailingZeros++;
    }
    if (trailingZeros > 0) {
      // Keep at least one decimal place
      final newScale = math.max(1, parsed._scale - trailingZeros);
      final factor = pow10(parsed._scale - newScale);
      final newValue = parsed._value ~/ factor;
      parsed = Decimal(newValue, newScale);
    }
  } else if (parsed._scale == 0 && isIntegerValued && this.abs() < 1e15) {
    // For integer-valued doubles, keep one decimal place
    parsed = Decimal(BigInt.from((this * 10).round()), 1);
  }

  if (scale != null && mode != null) {
    return parsed.withScale(scale, mode);
  }
  return parsed;
}