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

/// | |

/// **See also:** | |

/// * [int]: An integer number. | |

/// * [double]: A double-precision floating point number. | |

/// * [Numbers](https://dart.dev/guides/language/numbers) in | |

/// [A tour of the Dart language](https://dart.dev/guides/language/language-tour). | |

abstract class num implements Comparable<num> { | |

/// Test whether this value is numerically equal to `other`. | |

/// | |

/// If both operands are [double]s, 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 | |

/// the numbers have the same numerical value. | |

/// | |

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

/// ```dart | |

/// 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); | |

/// Adds [other] to this number. | |

/// | |

/// The result is an [int], as described by [int.+], | |

/// if both this number and [other] is an integer, | |

/// otherwise the result is a [double]. | |

num operator +(num other); | |

/// Subtracts [other] from this number. | |

/// | |

/// The result is an [int], as described by [int.-], | |

/// if both this number and [other] is an integer, | |

/// otherwise the result is a [double]. | |

num operator -(num other); | |

/// Multiplies this number by [other]. | |

/// | |

/// The result is an [int], as described by [int.*], | |

/// if both this number and [other] are integers, | |

/// otherwise the result is a [double]. | |

num operator *(num other); | |

/// Euclidean modulo of this number by [other]. | |

/// | |

/// 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, `q` is still an integer, | |

/// but `r` may have a non-integer value that still satisfies `0 <= r < |b|`. | |

/// | |

/// The sign of the returned value `r` is always positive. | |

/// | |

/// See [remainder] for the remainder of the truncating division. | |

/// | |

/// The result is an [int], as described by [int.%], | |

/// if both this number and [other] are integers, | |

/// otherwise the result is a [double]. | |

/// | |

/// Example: | |

/// ```dart | |

/// print(5 % 3); // 2 | |

/// print(-5 % 3); // 1 | |

/// print(5 % -3); // 2 | |

/// print(-5 % -3); // 1 | |

/// ``` | |

num operator %(num other); | |

/// Divides this number by [other]. | |

double operator /(num other); | |

/// Truncating division operator. | |

/// | |

/// Performs truncating division of this number by [other]. | |

/// Truncating division is division where a fractional result | |

/// is converted to an integer by rounding towards zero. | |

/// | |

/// If both operands are [int]s, then [other] must not be zero. | |

/// Then `a ~/ b` corresponds to `a.remainder(b)` | |

/// such that `a == (a ~/ b) * b + a.remainder(b)`. | |

/// | |

/// If either operand is a [double], then the other operand is converted | |

/// to a double before performing the division and truncation of the result. | |

/// Then `a ~/ b` is equivalent to `(a / b).truncate()`. | |

/// This means that the intermediate result of the double division | |

/// must be a finite integer (not an infinity or [double.nan]). | |

int operator ~/(num other); | |

/// The negation of this value. | |

/// | |

/// The negation of a number is a number of the same kind | |

/// (`int` or `double`) representing the negation of the | |

/// numbers numerical value (the result of subtracting the | |

/// number from zero), if that value *exists*. | |

/// | |

/// Negating a double gives a number with the same magnitude | |

/// as the original value (`number.abs() == (-number).abs()`), | |

/// and the opposite sign (`-(number.sign) == (-number).sign`). | |

/// | |

/// Negating an integer, `-number`, is equivalent to subtracting | |

/// it from zero, `0 - number`. | |

/// | |

/// (Both properties generally also hold for the other type, | |

/// but with a few edge case exceptions). | |

num operator -(); | |

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

/// | |

/// The result is an [int], as described by [int.remainder], | |

/// if both this number and [other] are integers, | |

/// otherwise the result is a [double]. | |

/// | |

/// Example: | |

/// ```dart | |

/// print(5.remainder(3)); // 2 | |

/// print(-5.remainder(3)); // -2 | |

/// print(5.remainder(-3)); // 2 | |

/// print(-5.remainder(-3)); // -2 | |

/// ``` | |

num remainder(num other); | |

/// Whether this number is numerically smaller than [other]. | |

/// | |

/// Returns `true` if this number is smaller than [other]. | |

/// Returns `false` if this number is greater than or equal to [other] | |

/// or if either value is a NaN value like [double.nan]. | |

bool operator <(num other); | |

/// Whether this number is numerically smaller than or equal to [other]. | |

/// | |

/// Returns `true` if this number is smaller than or equal to [other]. | |

/// Returns `false` if this number is greater than [other] | |

/// or if either value is a NaN value like [double.nan]. | |

bool operator <=(num other); | |

/// Whether this number is numerically greater than [other]. | |

/// | |

/// Returns `true` if this number is greater than [other]. | |

/// Returns `false` if this number is smaller than or equal to [other] | |

/// or if either value is a NaN value like [double.nan]. | |

bool operator >(num other); | |

/// Whether this number is numerically greater than or equal to [other]. | |

/// | |

/// Returns `true` if this number is greater than or equal to [other]. | |

/// Returns `false` if this number is smaller than [other] | |

/// or if either value is a NaN value like [double.nan]. | |

bool operator >=(num other); | |

/// Whether this number is a Not-a-Number value. | |

/// | |

/// Is `true` if this number is the [double.nan] value | |

/// or any other of the possible [double] NaN values. | |

/// Is `false` if this number is an integer, | |

/// a finite double or an infinite double ([double.infinity] | |

/// or [double.negativeInfinity]). | |

/// | |

/// All numbers satisfy exactly one of [isInfinite], [isFinite] | |

/// and `isNaN`. | |

bool get isNaN; | |

/// Whether this number is negative. | |

/// | |

/// A number is negative if it's smaller than zero, | |

/// or if it is the double `-0.0`. | |

/// This precludes a NaN value like [double.nan] from being negative. | |

bool get isNegative; | |

/// Whether this number is positive infinity or negative infinity. | |

/// | |

/// Only satisfied by [double.infinity] and [double.negativeInfinity]. | |

/// | |

/// All numbers satisfy exactly one of `isInfinite`, [isFinite] | |

/// and [isNaN]. | |

bool get isInfinite; | |

/// Whether this number is finite. | |

/// | |

/// The only non-finite numbers are NaN values, positive infinity, and | |

/// negative infinity. All integers are finite. | |

/// | |

/// All numbers satisfy exactly one of [isInfinite], `isFinite` | |

/// and [isNaN]. | |

bool get isFinite; | |

/// The absolute value of this number. | |

/// | |

/// The absolute value is the value itself, if the value is non-negative, | |

/// and `-value` if the value is negative. | |

/// | |

/// Integer overflow may cause the result of `-value` to stay negative. | |

/// | |

/// ```dart | |

/// print((2).abs()); // 2 | |

/// print((-2.5).abs()); // 2.5 | |

/// ``` | |

num abs(); | |

/// Negative one, zero or positive one depending on the sign and | |

/// numerical value of this number. | |

/// | |

/// The value minus one if this number is less than zero, | |

/// plus one if this number is greater than zero, | |

/// and zero if this number is equal to zero. | |

/// | |

/// Returns NaN if this number is a [double] NaN value. | |

/// | |

/// Returns a number of the same type as this number. | |

/// For doubles, `(-0.0).sign` is `-0.0`. | |

/// | |

/// The result satisfies: | |

/// ```dart | |

/// n == n.sign * n.abs() | |

/// ``` | |

/// for all numbers `n` (except NaN, because NaN isn't `==` to itself). | |

num get sign; | |

/// The integer closest to this number. | |

/// | |

/// Rounds away from zero when there is no closest integer: | |

/// `(3.5).round() == 4` and `(-3.5).round() == -4`. | |

/// | |

/// The number must be finite (see [isFinite]). | |

/// | |

/// If the value is greater than the highest representable positive integer, | |

/// the result is that highest positive integer. | |

/// If the value is smaller than the highest representable negative integer, | |

/// the result is that highest negative integer. | |

int round(); | |

/// The greatest integer no greater than this number. | |

/// | |

/// Rounds fractional values towards negative infinity. | |

/// | |

/// The number must be finite (see [isFinite]). | |

/// | |

/// If the value is greater than the highest representable positive integer, | |

/// the result is that highest positive integer. | |

/// If the value is smaller than the highest representable negative integer, | |

/// the result is that highest negative integer. | |

int floor(); | |

/// The least integer no smaller than `this`. | |

/// | |

/// Rounds fractional values towards positive infinity. | |

/// | |

/// The number must be finite (see [isFinite]). | |

/// | |

/// If the value is greater than the highest representable positive integer, | |

/// the result is that highest positive integer. | |

/// If the value is smaller than the highest representable negative integer, | |

/// the result is that highest negative integer. | |

int ceil(); | |

/// The integer obtained by discarding any fractional digits from `this`. | |

/// | |

/// Rounds fractional values towards zero. | |

/// | |

/// The number must be finite (see [isFinite]). | |

/// | |

/// If the value is greater than the highest representable positive integer, | |

/// the result is that highest positive integer. | |

/// If the value is smaller than the highest representable negative integer, | |

/// the result is that highest negative integer. | |

int truncate(); | |

/// The double integer value closest to this value. | |

/// | |

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

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

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

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

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

/// | |

/// Example: | |

/// ```dart | |

/// var result = 10.5.clamp(5, 10.0); // 10.0 | |

/// result = 0.75.clamp(5, 10.0); // 5 | |

/// result = (-10).clamp(-5, 5.0); // -5 | |

/// result = (-0.0).clamp(-5, 5.0); // -0.0 | |

/// ``` | |

num clamp(num lowerLimit, num upperLimit); | |

/// Truncates this [num] to an integer and returns the result as an [int]. | |

/// | |

/// Equivalent to [truncate]. | |

int toInt(); | |

/// This number as a [double]. | |

/// | |

/// If an integer number is not precisely representable as a [double], | |

/// an approximation is returned. | |

double toDouble(); | |

/// A decimal-point string-representation of this number. | |

/// | |

/// Converts this number to a [double] | |

/// before computing the string representation, | |

/// as by [toDouble]. | |

/// | |

/// If the absolute value of `this` is greater than 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: | |

/// ```dart | |

/// 1.toStringAsFixed(3); // 1.000 | |

/// (4321.12345678).toStringAsFixed(3); // 4321.123 | |

/// (4321.12345678).toStringAsFixed(5); // 4321.12346 | |

/// 123456789012345.toStringAsFixed(3); // 123456789012345.000 | |

/// 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000 | |

/// 5.25.toStringAsFixed(0); // 5 | |

/// ``` | |

String toStringAsFixed(int fractionDigits); | |

/// An exponential string-representation of this number. | |

/// | |

/// Converts this number 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 number. | |

/// | |

/// If [fractionDigits] equals 0, then the decimal point is omitted. | |

/// Examples: | |

/// ```dart | |

/// 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]); | |

/// A string representation with [precision] significant digits. | |

/// | |

/// Converts this number to a [double] | |

/// and returns a string representation of that value | |

/// with exactly [precision] significant digits. | |

/// | |

/// The parameter [precision] must be an integer satisfying: | |

/// `1 <= precision <= 21`. | |

/// | |

/// Examples: | |

/// ```dart | |

/// 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); | |

/// The shortest string that correctly represents this 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: | |

/// ```dart | |

/// (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) ?? (...)`. | |

/// | |

/// Examples: | |

/// ```dart | |

/// var value = num.parse('2021'); // 2021 | |

/// value = num.parse('3.14'); // 3.14 | |

/// value = num.parse(' 3.14 \xA0'); // 3.14 | |

/// value = num.parse('0.'); // 0.0 | |

/// value = num.parse('.0'); // 0.0 | |

/// value = num.parse('-1.e3'); // -1000.0 | |

/// value = num.parse('1234E+7'); // 12340000000.0 | |

/// value = num.parse('+.12e-9'); // 1.2e-10 | |

/// value = num.parse('-NaN'); // NaN | |

/// value = num.parse('0xFF'); // 255 | |

/// value = num.parse(double.infinity.toString()); // Infinity | |

/// value = num.parse('1f'); // Throws. | |

/// ``` | |

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

/// | |

/// Examples: | |

/// ```dart | |

/// var value = num.tryParse('2021'); // 2021 | |

/// value = num.tryParse('3.14'); // 3.14 | |

/// value = num.tryParse(' 3.14 \xA0'); // 3.14 | |

/// value = num.tryParse('0.'); // 0.0 | |

/// value = num.tryParse('.0'); // 0.0 | |

/// value = num.tryParse('-1.e3'); // -1000.0 | |

/// value = num.tryParse('1234E+7'); // 12340000000.0 | |

/// value = num.tryParse('+.12e-9'); // 1.2e-10 | |

/// value = num.tryParse('-NaN'); // NaN | |

/// value = num.tryParse('0xFF'); // 255 | |

/// value = num.tryParse(double.infinity.toString()); // Infinity | |

/// value = num.tryParse('1f'); // null | |

/// ``` | |

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); | |

} | |

} |