valueToString function

String valueToString(
  1. double value,
  2. int significantFigures,
  3. bool removeTrailingZeros,
  4. bool useScientificNotation,
  5. String decimalSeparator,
)

Given a double value it returns its representation as a string with few tweaks: significantFigures is the number of significant figures to keep, removeTrailingZeros say if non important zeros should be removed. decimalSeparator is the string used to separate the integer part from the decimal one (default is "."). E.g. 1.000000 --> 1

Implementation

String valueToString(
  double value,
  int significantFigures,
  bool removeTrailingZeros,
  bool useScientificNotation,
  String decimalSeparator,
) {
  //Round to a fixed number of significant figures
  String stringValue;
  if (useScientificNotation) {
    stringValue = value.toStringAsPrecision(significantFigures);
  } else {
    stringValue = value.toStringAsFixed(significantFigures);
  }

  /**
   * [stringValue] can be in multiple form:
   *  - x     (an integer)
   *  - x.y   (a decimal)
   *  - xez   (integer with an exponential part)
   *  - x.yez (decimal with an exponential part)
   */

  List<String> splittedNumbers = stringValue.split('.');
  String integerPart = splittedNumbers[0];
  String? decimalPart, exponentialPart;

  // x.y and x.yez
  if (splittedNumbers.length == 2) {
    splittedNumbers = splittedNumbers[1].split('e');
    decimalPart = splittedNumbers[0];

    // x.yez
    if (splittedNumbers.length == 2) {
      exponentialPart = splittedNumbers[1];
    }
  }
  // x and xez
  else {
    splittedNumbers = splittedNumbers[0].split('e');

    // xez
    if (splittedNumbers.length == 2) {
      integerPart = splittedNumbers[0];
      exponentialPart = splittedNumbers[1];
    }
  }

  //if the user want to remove the trailing zeros
  if (removeTrailingZeros && decimalPart != null) {
    //remove trailing zeros (just fractional part)
    int firstZeroIndex = decimalPart.length;
    for (; firstZeroIndex > 0; firstZeroIndex--) {
      String charAtIndex =
          decimalPart.substring(firstZeroIndex - 1, firstZeroIndex);
      if (charAtIndex != '0') break;
    }
    decimalPart = decimalPart.substring(0, firstZeroIndex);
    if (decimalPart == "") {
      decimalPart = null;
    }
  }

  if (!useScientificNotation && exponentialPart != null) {
    // It means that the absolute value of [value] is greater or equal than 1e21
    // (see the documentation of .toStringAsFixed() method)

    /**
     *  There are 2 cases:
     *  - x.ye+z
     *  - xe+z
     */
    int exponentialNumber = int.parse(exponentialPart);
    // x.ye+z
    if (decimalPart != null) {
      if (decimalPart.length < exponentialNumber) {
        decimalPart = decimalPart +
            ''.padRight(exponentialNumber - decimalPart.length, '0');
      }
      integerPart = integerPart + decimalPart.substring(0, exponentialNumber);
      decimalPart = decimalPart.substring(exponentialNumber);
      if (decimalPart == '') decimalPart = null;
    }
    // xe+z
    else {
      integerPart = integerPart + ''.padRight(exponentialNumber, '0');
    }
    exponentialPart = null;
  }

  // Recompose the string
  String finalString = integerPart;
  if (decimalPart != null) {
    finalString = '$finalString$decimalSeparator$decimalPart';
  }
  if (exponentialPart != null) {
    finalString = '${finalString}e$exponentialPart';
  }
  return finalString;
}