// 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.

part of dart.core;

/**
 * An integer or floating-point number.
 *
 * It is a compile-time error for any type other than [int] or [double]
 * to attempt to extend or implement num.
 */
abstract class num implements Comparable<num> {
  /**
   * Test whether this value is numerically equal to `other`.
   *
   * If both operands are doubles, they are equal if they have the same
   * representation, except that:
   *   * zero and minus zero (0.0 and -0.0) are considered equal. They
   *     both have the numerical value zero.
   *   * NaN is not equal to anything, including NaN. If either operand is
   *     NaN, the result is always false.
   *
   * If one operand is a double and the other is an int, they are equal if
   * the double has an integer value (finite with no fractional part) and
   * `identical(doubleValue.toInt(), intValue)`.
   *
   * If both operands are integers, they are equal if they have the same value.
   *
   * Returns false if `other` is not a [num].
   *
   * Notice that the behavior for NaN is non-reflexive. This means that
   * equality of double values is not a proper equality relation, as is
   * otherwise required of `operator==`. Using NaN in, e.g., a [HashSet]
   * will fail to work. The behavior is the standard IEEE-754 equality of
   * doubles.
   *
   * If you can avoid NaN values, the remaining doubles do have a proper eqality
   * relation, and can be used safely.
   *
   * Use [compareTo] for a comparison that distinguishes zero and minus zero,
   * and that considers NaN values as equal.
   */
  bool operator==(Object other);

  /**
   * Returns a hash code for a numerical value.
   *
   * The hash code is compatible with equality. It returns the same value
   * for an [int] and a [double] with the same numerical value, and therefore
   * the same value for the doubles zero and minus zero.
   *
   * No guarantees are made about the hash code of NaN.
   */
  int get hashCode;

  /**
   * Compares this to `other`.
   *
   * Returns a negative number if `this` is less than `other`, zero if they are
   * equal, and a positive number if `this` is greater than `other`.
   *
   * The orderding represented by this method is a total ordering of [num]
   * values. All distinct doubles are non-equal, as are all distinct integers,
   * but integers are equal to doubles if they have the same numerical
   * value.
   *
   * For ordering, the double NaN value is considered equal to itself, and
   * greater than any numeric value (unlike its behavior in `operator==`).
   *
   * The double value -0.0 is considered less than 0.0 (and the integer 0), but
   * greater than any non-zero negative value.
   *
   * Positive infinity is greater than any finite value (any value apart from
   * itself and NaN), and negative infinity is less than any other value.
   *
   * All other values are compared using their numeric value.
   */
  int compareTo(num other);

  /** Addition operator. */
  num operator +(num other);

  /** Subtraction operator. */
  num operator -(num other);

  /** Multiplication operator. */
  num operator *(num other);

  /**
   * Euclidean modulo operator.
   *
   * Returns the remainder of the euclidean division. The euclidean division of
   * two integers `a` and `b` yields two integers `q` and `r` such that
   * `a == b*q + r` and `0 <= r < a.abs()`.
   *
   * The euclidean division is only defined for integers, but can be easily
   * extended to work with doubles. In that case `r` may have a non-integer
   * value, but it still verifies `0 <= r < |a|`.
   *
   * The sign of the returned value `r` is always positive.
   *
   * See [remainder] for the remainder of the truncating division.
   */
  num operator %(num other);

  /** Division operator. */
  double operator /(num other);

  /**
   * Truncating division operator.
   *
   * If either operand is a [double] then the result of the truncating division
   * [:a ~/ b:] is equivalent to [:(a / b).truncate().toInt():].
   *
   * If both operands are [int]s then [:a ~/ b:] performs the truncating
   * integer division.
   */
  int operator ~/(num other);

  /** Negate operator. */
  num operator -();

 /**
   * Returns the remainder of the truncating division of `this` by [other].
   *
   * The result `r` of this operation satisfies: `this == this ~/ other + r`.
   * As a consequence the remainder `r` has the same sign as the dividend
   * `this`.
   */
  num remainder(num other);

  /** Relational less than operator. */
  bool operator <(num other);

  /** Relational less than or equal operator. */
  bool operator <=(num other);

  /** Relational greater than operator. */
  bool operator >(num other);

  /** Relational greater than or equal operator. */
  bool operator >=(num other);

  /** True if the number is the double Not-a-Number value; otherwise, false. */
  bool get isNaN;

  /**
   * True if the number is negative; otherwise, false.
   *
   * Negative numbers are those less than zero, and the double `-0.0`.
   */
  bool get isNegative;

  /**
   * True if the number is positive infinity or negative infinity; otherwise,
   * false.
   */
  bool get isInfinite;

  /**
   * True if the number is finite; otherwise, false.
   *
   * The only non-finite numbers are NaN, positive infinitity and
   * negative infinity.
   */
  bool get isFinite;

  /** Returns the absolute value of this [num]. */
  num abs();

  /**
   * Returns the integer closest to `this`.
   *
   * Rounds away from zero when there is no closest integer:
   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
   *
   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
   */
  int round();

  /**
   * Returns the greatest integer no greater than `this`.
   *
   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
   */
  int floor();

  /**
   * Returns the least integer no smaller than `this`.
   *
   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
   */
  int ceil();

  /**
   * Returns the integer obtained by discarding any fractional
   * digits from `this`.
   *
   * If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
   */
  int truncate();

  /**
   * Returns the integer value closest to `this`.
   *
   * Rounds away from zero when there is no closest integer:
   *  [:(3.5).round() == 4:] and [:(-3.5).round() == -4:].
   *
   * The result is a double.
   */
  double roundToDouble();

  /**
   * Returns the greatest integer value no greater than `this`.
   *
   * The result is a double.
   */
  double floorToDouble();

  /**
   * Returns the least integer value no smaller than `this`.
   *
   * The result is a double.
   */
  double ceilToDouble();

  /**
   * Returns the integer obtained by discarding any fractional
   * digits from `this`.
   *
   * The result is a double.
   */
  double truncateToDouble();

  /**
   * Clamps [this] to be in the range [lowerLimit]-[upperLimit]. The comparison
   * is done using [compareTo] and therefore takes [:-0.0:] into account.
   * It also implies that [double.NAN] is treated as the maximal double value.
   */
  num clamp(num lowerLimit, num upperLimit);

  /** Truncates this [num] to an integer and returns the result as an [int]. */
  int toInt();

  /**
   * Return this [num] as a [double].
   *
   * If the number is not representable as a [double], an
   * approximation is returned. For numerically large integers, the
   * approximation may be infinite.
   */
  double toDouble();

  /**
   * Returns a decimal-point string-representation of `this`.
   *
   * Converts `this` to a [double] before computing the string representation.
   *
   * If the absolute value of `this` is greater or equal to `10^21` then this
   * methods returns an exponential representation computed by
   * `this.toStringAsExponential()`. Otherwise the result
   * is the closest string representation with exactly [fractionDigits] digits
   * after the decimal point. If [fractionDigits] equals 0 then the decimal
   * point is omitted.
   *
   * The parameter [fractionDigits] must be an integer satisfying:
   * [:0 <= fractionDigits <= 20:].
   *
   * Examples:
   *
   *     1.toStringAsFixed(3);  // 1.000
   *     (4321.12345678).toStringAsFixed(3);  // 4321.123
   *     (4321.12345678).toStringAsFixed(5);  // 4321.12346
   *     123456789012345678901.toStringAsFixed(3);  // 123456789012345683968.000
   *     1000000000000000000000.toStringAsFixed(3); // 1e+21
   *     5.25.toStringAsFixed(0); // 5
   */
  String toStringAsFixed(int fractionDigits);

  /**
   * Returns an exponential string-representation of `this`.
   *
   * Converts `this` to a [double] before computing the string representation.
   *
   * If [fractionDigits] is given then it must be an integer satisfying:
   * [:0 <= fractionDigits <= 20:]. In this case the string contains exactly
   * [fractionDigits] after the decimal point. Otherwise, without the parameter,
   * the returned string uses the shortest number of digits that accurately
   * represent [this].
   *
   * If [fractionDigits] equals 0 then the decimal point is omitted.
   * Examples:
   *
   *     1.toStringAsExponential();       // 1e+0
   *     1.toStringAsExponential(3);      // 1.000e+0
   *     123456.toStringAsExponential();  // 1.23456e+5
   *     123456.toStringAsExponential(3); // 1.235e+5
   *     123.toStringAsExponential(0);    // 1e+2
   */
  String toStringAsExponential([int fractionDigits]);

  /**
   * Converts `this` to a double and returns a string representation with
   * exactly [precision] significant digits.
   *
   * The parameter [precision] must be an integer satisfying:
   * [:1 <= precision <= 21:].
   *
   * Examples:
   *
   *     1.toStringAsPrecision(2);       // 1.0
   *     1e15.toStringAsPrecision(3);    // 1.00+15
   *     1234567.toStringAsPrecision(3); // 1.23e+6
   *     1234567.toStringAsPrecision(9); // 1234567.00
   *     12345678901234567890.toStringAsPrecision(20); // 12345678901234567168
   *     12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19
   *     0.00000012345.toPrecision(15); // 1.23450000000000e-7
   *     0.0000012345.toPrecision(15);  // 0.00000123450000000000
   */
  String toStringAsPrecision(int precision);

  /**
   * Returns the shortest string that correctly represent the input number.
   *
   * All [double]s in the range `10^-6` (inclusive) to `10^21` (exclusive)
   * are converted to their decimal representation with at least one digit
   * after the decimal point. For all other doubles,
   * except for special values like `NaN` or `Infinity`, this method returns an
   * exponential representation (see [toStringAsExponential]).
   *
   * Returns `"NaN"` for [double.NAN], `"Infinity"` for [double.INFINITY], and
   * `"-Infinity"` for [double.MINUS_INFINITY].
   *
   * An [int] is converted to a decimal representation with no decimal point.
   *
   * Examples:
   *
   *     (0.000001).toString();  // "0.000001"
   *     (0.0000001).toString(); // "1e-7"
   *     (111111111111111111111.0).toString();  // "111111111111111110000.0"
   *     (100000000000000000000.0).toString();  // "100000000000000000000.0"
   *     (1000000000000000000000.0).toString(); // "1e+21"
   *     (1111111111111111111111.0).toString(); // "1.1111111111111111e+21"
   *     1.toString(); // "1"
   *     111111111111111111111.toString();  // "111111111111111110000"
   *     100000000000000000000.toString();  // "100000000000000000000"
   *     1000000000000000000000.toString(); // "1000000000000000000000"
   *     1111111111111111111111.toString(); // "1111111111111111111111"
   *     1.234e5.toString();   // 123400
   *     1234.5e6.toString();  // 1234500000
   *     12.345e67.toString(); // 1.2345e+68
   *
   * Note: the conversion may round the output if the returned string
   * is accurate enough to uniquely identify the input-number.
   * For example the most precise representation of the [double] `9e59` equals
   * `"899999999999999918767229449717619953810131273674690656206848"`, but
   * this method returns the shorter (but still uniquely identifying) `"9e59"`.
   *
   */
  String toString();

  /**
   * Parses a string containing a number literal into a number.
   *
   * The method first tries to read the [input] as integer (similar to
   * [int.parse] without a radix).
   * If that fails, it tries to parse the [input] as a double (similar to
   * [double.parse]).
   * If that fails, too, it invokes [onError] with [input].
   *
   * If no [onError] is supplied, it defaults to a function that throws a
   * [FormatException].
   *
   * For any number `n`, this function satisfies
   * `identical(n, num.parse(n.toString()))`.
   */
  static num parse(String input, [num onError(String input)]) {
    String source = input.trim();
    // TODO(lrn): Optimize to detect format and result type in one check.
    num result = int.parse(source, onError: _returnNull);
    if (result != null) return result;
    result = double.parse(source, _returnNull);
    if (result != null) return result;
    if (onError == null) throw new FormatException(input);
    return onError(input);
  }

  /** Helper function for [parse]. */
  static _returnNull(_) => null;
}
