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

// @dart = 2.5

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)` is true.
   *
   * 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
   * equality 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 values.
   */
  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 ordering 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 doubles, the `compareTo` operation is different from the partial
   * ordering given by [operator==], [operator<] and [operator>]. For example,
   * IEEE doubles impose that `0.0 == -0.0` and all comparison operations on
   * NaN return false.
   *
   * This function imposes a complete ordering for doubles. When using
   * `compareTo` the following properties hold:
   *
   * - All NaN values are considered equal, and greater than any numeric value.
   * - -0.0 is less than 0.0 (and the integer 0), but greater than any non-zero
   *    negative value.
   * - Negative infinity is less than all other values and positive infinity is
   *   greater than all non-NaN values.
   * - All other values are compared using their numeric value.
   *
   * Examples:
   * ```
   * print(1.compareTo(2)); // => -1
   * print(2.compareTo(1)); // => 1
   * print(1.compareTo(1)); // => 0
   *
   * // The following comparisons yield different results than the
   * // corresponding comparison operators.
   * print((-0.0).compareTo(0.0));  // => -1
   * print(double.nan.compareTo(double.nan));  // => 0
   * print(double.infinity.compareTo(double.nan)); // => -1
   *
   * // -0.0, and NaN comparison operators have rules imposed by the IEEE
   * // standard.
   * print(-0.0 == 0.0); // => true
   * print(double.nan == double.nan);  // => false
   * print(double.infinity < double.nan);  // => false
   * print(double.nan < double.infinity);  // => false
   * print(double.nan == double.infinity);  // => false
   * ```
   */
  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 < b.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 < |b|`.
   *
   * 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) * other + r`.
   * As a consequence the remainder `r` has the same sign as the divider `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 infinity, and
   * negative infinity.
   */
  bool get isFinite;

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

  /**
   * Returns minus one, zero or plus one depending on the sign and
   * numerical value of the number.
   *
   * Returns minus one if the number is less than zero,
   * plus one if the number is greater than zero,
   * and zero if the number is equal to zero.
   *
   * Returns NaN if the number is the double NaN value.
   *
   * Returns a number of the same type as this number.
   * For doubles, `-0.0.sign == -0.0`.

   * The result satisfies:
   *
   *     n == n.sign * n.abs()
   *
   * for all numbers `n` (except NaN, because NaN isn't `==` to itself).
   */
  num get sign;

  /**
   * 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 double integer value closest to `this`.
   *
   * Rounds away from zero when there is no closest integer:
   *  `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
   *
   * If this is already an integer valued double, including `-0.0`, or it is a
   * non-finite double value, the value is returned unmodified.
   *
   * For the purpose of rounding, `-0.0` is considered to be below `0.0`,
   * and `-0.0` is therefore considered closer to negative numbers than `0.0`.
   * This means that for a value, `d` in the range `-0.5 < d < 0.0`,
   * the result is `-0.0`.
   *
   * The result is always a double.
   * If this is a numerically large integer, the result may be an infinite
   * double.
   */
  double roundToDouble();

  /**
   * Returns the greatest double integer value no greater than `this`.
   *
   * If this is already an integer valued double, including `-0.0`, or it is a
   * non-finite double value, the value is returned unmodified.
   *
   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
   * A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
   *
   * The result is always a double.
   * If this is a numerically large integer, the result may be an infinite
   * double.
   */
  double floorToDouble();

  /**
   * Returns the least double integer value no smaller than `this`.
   *
   * If this is already an integer valued double, including `-0.0`, or it is a
   * non-finite double value, the value is returned unmodified.
   *
   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
   *
   * The result is always a double.
   * If this is a numerically large integer, the result may be an infinite
   * double.
   */
  double ceilToDouble();

  /**
   * Returns the double integer value obtained by discarding any fractional
   * digits from the double value of `this`.
   *
   * If this is already an integer valued double, including `-0.0`, or it is a
   * non-finite double value, the value is returned unmodified.
   *
   * For the purpose of rounding, `-0.0` is considered to be below `0.0`.
   * A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
   * in the range `0.0 < d < 1.0` it will return 0.0.
   *
   * The result is always a double.
   * If this is a numerically large integer, the result may be an infinite
   * double.
   */
  double truncateToDouble();

  /**
   * Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit].
   *
   * The comparison is done using [compareTo] and therefore takes `-0.0` into
   * account. This also implies that [double.nan] is treated as the maximal
   * double value.
   *
   * The arguments [lowerLimit] and [upperLimit] must form a valid range where
   * `lowerLimit.compareTo(upperLimit) <= 0`.
   */
  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.00e+15
   *     1234567.toStringAsPrecision(3); // 1.23e+6
   *     1234567.toStringAsPrecision(9); // 1234567.00
   *     12345678901234567890.toStringAsPrecision(20); // 12345678901234567168
   *     12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19
   *     0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7
   *     0.0000012345.toStringAsPrecision(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.negativeInfinity].
   *
   * 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], and the result
   * of that invocation becomes the result of calling `parse`.
   *
   * 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()))` (except when `n` is a NaN `double`
   * with a payload).
   *
   * The [onError] parameter is deprecated and will be removed.
   * Instead of `num.parse(string, (string) { ... })`,
   * you should use `num.tryParse(string) ?? (...)`.
   */
  static num parse(String input, [@deprecated num onError(String input)]) {
    num result = tryParse(input);
    if (result != null) return result;
    if (onError == null) throw FormatException(input);
    return onError(input);
  }

  /**
   * Parses a string containing a number literal into a number.
   *
   * Like [parse] except that this function returns `null` for invalid inputs
   * instead of throwing.
   */
  static num tryParse(String input) {
    String source = input.trim();
    // TODO(lrn): Optimize to detect format and result type in one check.
    return int.tryParse(source) ?? double.tryParse(source);
  }

  /** Helper functions for [parse]. */
  static int _returnIntNull(String _) => null;
  static double _returnDoubleNull(String _) => null;
}
