<commit_before>// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#library("number_format");

#import('dart:math');

#import("intl.dart");
#import("number_symbols.dart");
#import("number_symbols_data.dart");

class NumberFormat {
  /** Variables to determine how number printing behaves. */
  // TODO(alanknight): If these remain as variables and are set based on the
  // pattern, can we make them final?
  String _negativePrefix = '-';
  String _positivePrefix = '';
  String _negativeSuffix = '';
  String _positiveSuffix = '';
  /** How many numbers in a group when using punctuation to group digits in
   * large numbers. e.g. in en_US: "1,000,000" has a grouping size of 3 digits
   * between commas.
   */
  int _groupingSize = 3;
  bool _decimalSeparatorAlwaysShown = false;
  bool _useExponentialNotation = false;
  int _maximumIntegerDigits = 40;
  int _minimumIntegerDigits = 1;
  int _maximumFractionDigits = 3; // invariant, >= minFractionDigits
  int _minimumFractionDigits = 0;
  int _minimumExponentDigits = 0;
  bool _useSignForPositiveExponent = false;

  /** The locale in which we print numbers. */
  final String _locale;

  /** Caches the symbols used for our locale. */
  NumberSymbols _symbols;

  /**
   * Transient internal state in which to build up the result of the format
   * operation. We can have this be just an instance variable because Dart is
   * single-threaded and unless we do an asynchronous operation in the process
   * of formatting then there will only ever be one number being formatted
   * at a time. In languages with threads we'd need to pass this on the stack.
   */
  StringBuffer _buffer;

  /**
   * Create a number format that prints in [newPattern] as it applies in
   * [locale].
   */
  NumberFormat([String newPattern, String locale]):
    _locale = Intl.verifiedLocale(locale) {
    // TODO(alanknight): There will need to be some kind of async setup
    // operations so as not to bring along every locale in every program.
    _symbols = numberFormatSymbols[_locale];
    _setPattern(newPattern);
  }

  /**
   * Return the locale code in which we operate, e.g. 'en_US' or 'pt'.
   */
  String get locale => _locale;

  /**
   * Return the symbols which are used in our locale. Cache them to avoid
   * repeated lookup.
   */
  NumberSymbols get symbols {
    return _symbols;
  }

  // TODO(alanknight): Actually use the pattern and locale.
  _setPattern(String x) {}

  /**
   * Format [number] according to our pattern and return the formatted string.
   */
  String format(num number) {
    // TODO(alanknight): Do we have to do anything for printing numbers bidi?
    // Or are they always printed left to right?
    if (number.isNaN()) return symbols.NAN;
    if (number.isInfinite()) return "${_signPrefix(number)}${symbols.INFINITY}";

    _newBuffer();
    _add(_signPrefix(number));
    _formatNumber(number.abs());
    _add(_signSuffix(number));

    var result = _buffer.toString();
    _buffer = null;
    return result;
  }

  /**
   * Format the main part of the number in the form dictated by the pattern.
   */
  void _formatNumber(num number) {
    if (_useExponentialNotation) {
      _formatExponential(number);
    } else {
      _formatFixed(number);
    }
  }

  /** Format the number in exponential notation. */
  _formatExponential(num number) {
    if (number == 0.0) {
      _formatFixed(number);
      _formatExponent(0);
      return;
    }

    var exponent = (log(number) / log(10)).floor();
    var mantissa = number / pow(10, exponent);

    if (_minimumIntegerDigits < 1) {
      exponent++;
      mantissa /= 10;
    } else {
      exponent -= _minimumIntegerDigits - 1;
      mantissa *= pow(10, _minimumIntegerDigits - 1);
    }
    _formatFixed(number);
    _formatExponent(exponent);
  }

  /**
   * Format the exponent portion, e.g. in "1.3e-5" the "e-5".
   */
  void _formatExponent(num exponent) {
    _add(symbols.EXP_SYMBOL);
    if (exponent < 0) {
      exponent = -exponent;
      _add(symbols.MINUS_SIGN);
    } else if (_useSignForPositiveExponent) {
      _add(symbols.PLUS_SIGN);
    }
    _pad(_minimumExponentDigits, exponent.toString());
  }

  /**
   * Format the basic number portion, inluding the fractional digits.
   */
  void _formatFixed(num number) {
    // Round the number.
    var power = pow(10, _maximumFractionDigits);
    var intValue = number.truncate().toInt();
    var multiplied = (number * power).round();
    var fracValue = (multiplied - intValue * power).floor().toInt();
    var fractionPresent = _minimumFractionDigits > 0 || fracValue > 0;

    // On dartj2s the integer part may be large enough to be a floating
    // point value, in which case we reduce it until it is small enough
    // to be printed as an integer and pad the remainder with zeros.
    var paddingDigits = new StringBuffer();
    while (intValue is! int) {
      paddingDigits.add(symbols.ZERO_DIGIT);
      intValue = (intValue / 10).toInt();
    }
    var integerDigits = "${intValue}${paddingDigits}".charCodes();
    var digitLength = integerDigits.length;

    if (_hasPrintableIntegerPart(intValue)) {
      _pad(_minimumIntegerDigits - digitLength);
      for (var i = 0; i < digitLength; i++) {
        _addDigit(integerDigits[i]);
        _group(digitLength, i);<commit_msg>Change our 'is int' check to use Math.floor instead of a smi check. Review URL: https://chromiumcodereview.appspot.com//10912147<commit_after>// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#library("number_format");

#import('dart:math');

#import("intl.dart");
#import("number_symbols.dart");
#import("number_symbols_data.dart");

class NumberFormat {
  /** Variables to determine how number printing behaves. */
  // TODO(alanknight): If these remain as variables and are set based on the
  // pattern, can we make them final?
  String _negativePrefix = '-';
  String _positivePrefix = '';
  String _negativeSuffix = '';
  String _positiveSuffix = '';
  /** How many numbers in a group when using punctuation to group digits in
   * large numbers. e.g. in en_US: "1,000,000" has a grouping size of 3 digits
   * between commas.
   */
  int _groupingSize = 3;
  bool _decimalSeparatorAlwaysShown = false;
  bool _useExponentialNotation = false;
  int _maximumIntegerDigits = 40;
  int _minimumIntegerDigits = 1;
  int _maximumFractionDigits = 3; // invariant, >= minFractionDigits
  int _minimumFractionDigits = 0;
  int _minimumExponentDigits = 0;
  bool _useSignForPositiveExponent = false;

  /** The locale in which we print numbers. */
  final String _locale;

  /** Caches the symbols used for our locale. */
  NumberSymbols _symbols;

  /**
   * Transient internal state in which to build up the result of the format
   * operation. We can have this be just an instance variable because Dart is
   * single-threaded and unless we do an asynchronous operation in the process
   * of formatting then there will only ever be one number being formatted
   * at a time. In languages with threads we'd need to pass this on the stack.
   */
  StringBuffer _buffer;

  /**
   * Create a number format that prints in [newPattern] as it applies in
   * [locale].
   */
  NumberFormat([String newPattern, String locale]):
    _locale = Intl.verifiedLocale(locale) {
    // TODO(alanknight): There will need to be some kind of async setup
    // operations so as not to bring along every locale in every program.
    _symbols = numberFormatSymbols[_locale];
    _setPattern(newPattern);
  }

  /**
   * Return the locale code in which we operate, e.g. 'en_US' or 'pt'.
   */
  String get locale => _locale;

  /**
   * Return the symbols which are used in our locale. Cache them to avoid
   * repeated lookup.
   */
  NumberSymbols get symbols {
    return _symbols;
  }

  // TODO(alanknight): Actually use the pattern and locale.
  _setPattern(String x) {}

  /**
   * Format [number] according to our pattern and return the formatted string.
   */
  String format(num number) {
    // TODO(alanknight): Do we have to do anything for printing numbers bidi?
    // Or are they always printed left to right?
    if (number.isNaN()) return symbols.NAN;
    if (number.isInfinite()) return "${_signPrefix(number)}${symbols.INFINITY}";

    _newBuffer();
    _add(_signPrefix(number));
    _formatNumber(number.abs());
    _add(_signSuffix(number));

    var result = _buffer.toString();
    _buffer = null;
    return result;
  }

  /**
   * Format the main part of the number in the form dictated by the pattern.
   */
  void _formatNumber(num number) {
    if (_useExponentialNotation) {
      _formatExponential(number);
    } else {
      _formatFixed(number);
    }
  }

  /** Format the number in exponential notation. */
  _formatExponential(num number) {
    if (number == 0.0) {
      _formatFixed(number);
      _formatExponent(0);
      return;
    }

    var exponent = (log(number) / log(10)).floor();
    var mantissa = number / pow(10, exponent);

    if (_minimumIntegerDigits < 1) {
      exponent++;
      mantissa /= 10;
    } else {
      exponent -= _minimumIntegerDigits - 1;
      mantissa *= pow(10, _minimumIntegerDigits - 1);
    }
    _formatFixed(number);
    _formatExponent(exponent);
  }

  /**
   * Format the exponent portion, e.g. in "1.3e-5" the "e-5".
   */
  void _formatExponent(num exponent) {
    _add(symbols.EXP_SYMBOL);
    if (exponent < 0) {
      exponent = -exponent;
      _add(symbols.MINUS_SIGN);
    } else if (_useSignForPositiveExponent) {
      _add(symbols.PLUS_SIGN);
    }
    _pad(_minimumExponentDigits, exponent.toString());
  }

  /**
   * Format the basic number portion, inluding the fractional digits.
   */
  void _formatFixed(num number) {
    // Round the number.
    var power = pow(10, _maximumFractionDigits);
    var intValue = number.truncate().toInt();
    var multiplied = (number * power).round();
    var fracValue = (multiplied - intValue * power).floor().toInt();
    var fractionPresent = _minimumFractionDigits > 0 || fracValue > 0;

    // On dartj2s the integer part may be large enough to be a floating
    // point value, in which case we reduce it until it is small enough
    // to be printed as an integer and pad the remainder with zeros.
    var paddingDigits = new StringBuffer();
    while ((intValue & 0x7fffffff) != intValue) {
      paddingDigits.add(symbols.ZERO_DIGIT);
      intValue = (intValue / 10).toInt();
    }
    var integerDigits = "${intValue}${paddingDigits}".charCodes();
    var digitLength = integerDigits.length;

    if (_hasPrintableIntegerPart(intValue)) {
      _pad(_minimumIntegerDigits - digitLength);
      for (var i = 0; i < digitLength; i++) {
        _addDigit(integerDigits[i]);
        _group(digitLength, i);
{'fraction_non_alphanumeric': 0.10574837310195227, 'fraction_numerical': 0.009219088937093275, 'mean_word_length': 3.131814787154593, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2926239', 'n_tokens_mistral': 3476, 'n_tokens_neox': 3303, 'n_words': 1122}