// 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 number. /// /// The default implementation of `int` is 64-bit two's complement integers /// with operations that wrap to that range on overflow. /// /// **Note:** When compiling to JavaScript, integers are restricted to values /// that can be represented exactly by double-precision floating point values. /// The available integer values include all integers between -2^53 and 2^53, /// and some integers with larger magnitude. That includes some integers larger /// than 2^63. /// The behavior of the operators and methods in the [int] /// class therefore sometimes differs between the Dart VM and Dart code /// compiled to JavaScript. For example, the bitwise operators truncate their /// operands to 32-bit integers when compiled to JavaScript. /// /// Classes cannot extend, implement, or mix in `int`. /// /// **See also:** /// * [num] the super class for [int]. /// * [Built-in number types](https://dart.dev/language/built-in-types#numbers) /// * [Number representation](https://dart.dev/resources/language/number-representation) abstract final class int extends num { /// Integer value for [name] in the compilation configuration environment. /// /// The compilation configuration environment is provided by the /// surrounding tools which are compiling or running the Dart program. /// The environment is a mapping from a set of string keys to their associated /// string value. /// The string value, or lack of a value, associated with a [name] /// must be consistent across all calls to [String.fromEnvironment], /// `int.fromEnvironment`, [bool.fromEnvironment] and [bool.hasEnvironment] /// in a single program. /// The string values can be directly accessed using /// [String.fromEnvironment]. /// /// This constructor looks up the string value for [name], /// then attempts to parse it as an integer, using the same syntax rules as /// [int.parse]/[int.tryParse]. That is, it accepts decimal numerals /// and hexadecimal numerals with a `0x` prefix, and it accepts a leading /// minus sign. /// If there is no value associated with [name] in the compilation /// configuration environment, or if the associated string value cannot /// be parsed as an integer, the value of the constructor invocation /// is the [defaultValue] integer, which defaults to the integer zero. /// /// The result is effectively the same as that of: /// ```dart template:expression /// int.tryParse(const String.fromEnvironment(name, defaultValue: "")) /// ?? defaultValue /// ``` /// except that the constructor invocation can be a constant value. /// /// Example: /// ```dart /// const defaultPort = int.fromEnvironment("defaultPort", defaultValue: 80); /// ``` /// In order to check whether a value is there at all, use /// [bool.hasEnvironment]. Example: /// ```dart /// const int? maybeDeclared = bool.hasEnvironment("defaultPort") /// ? int.fromEnvironment("defaultPort") /// : null; /// ``` /// /// The string value, or lack of a value, associated with a [name] /// must be consistent across all calls to [String.fromEnvironment], /// `int.fromEnvironment`, [bool.fromEnvironment] and [bool.hasEnvironment] /// in a single program. /// /// This constructor is only guaranteed to work when invoked as `const`. /// It may work as a non-constant invocation on some platforms which /// have access to compiler options at run-time, but most ahead-of-time /// compiled platforms will not have this information. external const factory int.fromEnvironment( String name, { int defaultValue = 0, }); /// Bit-wise and operator. /// /// Treating both `this` and [other] as sufficiently large two's component /// integers, the result is a number with only the bits set that are set in /// both `this` and [other] /// /// If both operands are negative, the result is negative, otherwise /// the result is non-negative. /// ```dart /// print((2 & 1).toRadixString(2)); // 0010 & 0001 -> 0000 /// print((3 & 1).toRadixString(2)); // 0011 & 0001 -> 0001 /// print((10 & 2).toRadixString(2)); // 1010 & 0010 -> 0010 /// ``` int operator &(int other); /// Bit-wise or operator. /// /// Treating both `this` and [other] as sufficiently large two's component /// integers, the result is a number with the bits set that are set in either /// of `this` and [other] /// /// If both operands are non-negative, the result is non-negative, /// otherwise the result is negative. /// /// Example: /// ```dart /// print((2 | 1).toRadixString(2)); // 0010 | 0001 -> 0011 /// print((3 | 1).toRadixString(2)); // 0011 | 0001 -> 0011 /// print((10 | 2).toRadixString(2)); // 1010 | 0010 -> 1010 /// ``` int operator |(int other); /// Bit-wise exclusive-or operator. /// /// Treating both `this` and [other] as sufficiently large two's component /// integers, the result is a number with the bits set that are set in one, /// but not both, of `this` and [other] /// /// If the operands have the same sign, the result is non-negative, /// otherwise the result is negative. /// /// Example: /// ```dart /// print((2 ^ 1).toRadixString(2)); // 0010 ^ 0001 -> 0011 /// print((3 ^ 1).toRadixString(2)); // 0011 ^ 0001 -> 0010 /// print((10 ^ 2).toRadixString(2)); // 1010 ^ 0010 -> 1000 /// ``` int operator ^(int other); /// The bit-wise negate operator. /// /// Treating `this` as a sufficiently large two's component integer, /// the result is a number with the opposite bits set. /// /// This maps any integer `x` to `-x - 1`. int operator ~(); /// Shift the bits of this integer to the left by [shiftAmount]. /// /// Shifting to the left makes the number larger, effectively multiplying /// the number by `pow(2, shiftAmount)`. /// /// There is no limit on the size of the result. It may be relevant to /// limit intermediate values by using the "and" operator with a suitable /// mask. /// /// It is an error if [shiftAmount] is negative. /// /// Example: /// ```dart /// print((3 << 1).toRadixString(2)); // 0011 -> 0110 /// print((9 << 2).toRadixString(2)); // 1001 -> 100100 /// print((10 << 3).toRadixString(2)); // 1010 -> 1010000 /// ``` int operator <<(int shiftAmount); /// Shift the bits of this integer to the right by [shiftAmount]. /// /// Shifting to the right makes the number smaller and drops the least /// significant bits, effectively doing an integer division by /// `pow(2, shiftAmount)`. /// /// It is an error if [shiftAmount] is negative. /// /// Example: /// ```dart /// print((3 >> 1).toRadixString(2)); // 0011 -> 0001 /// print((9 >> 2).toRadixString(2)); // 1001 -> 0010 /// print((10 >> 3).toRadixString(2)); // 1010 -> 0001 /// print((-6 >> 2).toRadixString); // 111...1010 -> 111...1110 == -2 /// print((-85 >> 3).toRadixString); // 111...10101011 -> 111...11110101 == -11 /// ``` int operator >>(int shiftAmount); /// Bitwise unsigned right shift by [shiftAmount] bits. /// /// The least significant [shiftAmount] bits are dropped, /// the remaining bits (if any) are shifted down, /// and zero-bits are shifted in as the new most significant bits. /// /// The [shiftAmount] must be non-negative. /// /// Example: /// ```dart /// print((3 >>> 1).toRadixString(2)); // 0011 -> 0001 /// print((9 >>> 2).toRadixString(2)); // 1001 -> 0010 /// print(((-9) >>> 2).toRadixString(2)); // 111...1011 -> 001...1110 (> 0) /// ``` int operator >>>(int shiftAmount); /// Returns this integer to the power of [exponent] modulo [modulus]. /// /// The [exponent] must be non-negative and [modulus] must be /// positive. int modPow(int exponent, int modulus); /// Returns the modular multiplicative inverse of this integer /// modulo [modulus]. /// /// The [modulus] must be positive. /// /// It is an error if no modular inverse exists. int modInverse(int modulus); /// Returns the greatest common divisor of this integer and [other]. /// /// If either number is non-zero, the result is the numerically greatest /// integer dividing both `this` and `other`. /// /// The greatest common divisor is independent of the order, /// so `x.gcd(y)` is always the same as `y.gcd(x)`. /// /// For any integer `x`, `x.gcd(x)` is `x.abs()`. /// /// If both `this` and `other` is zero, the result is also zero. /// /// Example: /// ```dart /// print(4.gcd(2)); // 2 /// print(8.gcd(4)); // 4 /// print(10.gcd(12)); // 2 /// print(10.gcd(0)); // 10 /// print((-2).gcd(-3)); // 1 /// ``` int gcd(int other); /// Returns true if and only if this integer is even. bool get isEven; /// Returns true if and only if this integer is odd. bool get isOdd; /// Returns the minimum number of bits required to store this integer. /// /// The number of bits excludes the sign bit, which gives the natural length /// for non-negative (unsigned) values. Negative values are complemented to /// return the bit position of the first bit that differs from the sign bit. /// /// To find the number of bits needed to store the value as a signed value, /// add one, i.e. use `x.bitLength + 1`. /// ```dart /// x.bitLength == (-x-1).bitLength; /// /// 3.bitLength == 2; // 00000011 /// 2.bitLength == 2; // 00000010 /// 1.bitLength == 1; // 00000001 /// 0.bitLength == 0; // 00000000 /// (-1).bitLength == 0; // 11111111 /// (-2).bitLength == 1; // 11111110 /// (-3).bitLength == 2; // 11111101 /// (-4).bitLength == 2; // 11111100 /// ``` int get bitLength; /// Returns the least significant [width] bits of this integer as a /// non-negative number (i.e. unsigned representation). The returned value has /// zeros in all bit positions higher than [width]. /// ```dart /// (-1).toUnsigned(5) == 31 // 11111111 -> 00011111 /// ``` /// This operation can be used to simulate arithmetic from low level languages. /// For example, to increment an 8 bit quantity: /// ```dart /// q = (q + 1).toUnsigned(8); /// ``` /// `q` will count from `0` up to `255` and then wrap around to `0`. /// /// If the input fits in [width] bits without truncation, the result is the /// same as the input. The minimum width needed to avoid truncation of `x` is /// given by `x.bitLength`, i.e. /// ```dart /// x == x.toUnsigned(x.bitLength); /// ``` int toUnsigned(int width); /// Returns the least significant [width] bits of this integer, extending the /// highest retained bit to the sign. This is the same as truncating the value /// to fit in [width] bits using an signed 2-s complement representation. The /// returned value has the same bit value in all positions higher than [width]. /// /// ```dart /// // V--sign bit-V /// 16.toSigned(5) == -16; // 00010000 -> 11110000 /// 239.toSigned(5) == 15; // 11101111 -> 00001111 /// // ^ ^ /// ``` /// This operation can be used to simulate arithmetic from low level languages. /// For example, to increment an 8 bit signed quantity: /// ```dart /// q = (q + 1).toSigned(8); /// ``` /// `q` will count from `0` up to `127`, wrap to `-128` and count back up to /// `127`. /// /// If the input value fits in [width] bits without truncation, the result is /// the same as the input. The minimum width needed to avoid truncation of `x` /// is `x.bitLength + 1`, i.e. /// ```dart /// x == x.toSigned(x.bitLength + 1); /// ``` int toSigned(int width); /// Return the negative value of this integer. /// /// The result of negating an integer always has the opposite sign, except /// for zero, which is its own negation. int operator -(); /// Returns the absolute value of this integer. /// /// For any integer `value`, /// the result is the same as `value < 0 ? -value : value`. /// /// Integer overflow may cause the result of `-value` to stay negative. int abs(); /// Returns the sign of this integer. /// /// Returns 0 for zero, -1 for values less than zero and /// +1 for values greater than zero. int get sign; /// Returns `this`. int round(); /// Returns `this`. int floor(); /// Returns `this`. int ceil(); /// Returns `this`. int truncate(); /// Returns `this.toDouble()`. double roundToDouble(); /// Returns `this.toDouble()`. double floorToDouble(); /// Returns `this.toDouble()`. double ceilToDouble(); /// Returns `this.toDouble()`. double truncateToDouble(); /// Returns a string representation of this integer. /// /// The returned string is parsable by [parse]. /// For any `int` `i`, it is guaranteed that /// `i == int.parse(i.toString())`. String toString(); /// Converts this [int] to a string representation in the given [radix]. /// /// In the string representation, lower-case letters are used for digits above /// '9', with 'a' being 10 and 'z' being 35. /// /// The [radix] argument must be an integer in the range 2 to 36. /// /// Example: /// ```dart /// // Binary (base 2). /// print(12.toRadixString(2)); // 1100 /// print(31.toRadixString(2)); // 11111 /// print(2021.toRadixString(2)); // 11111100101 /// print((-12).toRadixString(2)); // -1100 /// // Octal (base 8). /// print(12.toRadixString(8)); // 14 /// print(31.toRadixString(8)); // 37 /// print(2021.toRadixString(8)); // 3745 /// // Hexadecimal (base 16). /// print(12.toRadixString(16)); // c /// print(31.toRadixString(16)); // 1f /// print(2021.toRadixString(16)); // 7e5 /// // Base 36. /// print((35 * 36 + 1).toRadixString(36)); // z1 /// ``` String toRadixString(int radix); /// Parse [source] as a, possibly signed, integer literal and return its value. /// /// The [source] must be a non-empty sequence of base-[radix] digits, /// optionally prefixed with a minus or plus sign ('-' or '+'). /// /// The [radix] must be in the range 2..36. The digits used are /// first the decimal digits 0..9, and then the letters 'a'..'z' with /// values 10 through 35. Also accepts upper-case letters with the same /// values as the lower-case ones. /// /// If no [radix] is given then it defaults to 10. In this case, the [source] /// digits may also start with `0x`, in which case the number is interpreted /// as a hexadecimal integer literal, /// When `int` is implemented by 64-bit signed integers, /// hexadecimal integer literals may represent values larger than /// 263, in which case the value is parsed as if it is an /// *unsigned* number, and the resulting value is the corresponding /// signed integer value. /// /// For any int `n` and valid radix `r`, it is guaranteed that /// `n == int.parse(n.toRadixString(r), radix: r)`. /// /// If the [source] string does not contain a valid integer literal, /// optionally prefixed by a sign, a [FormatException] is thrown. /// /// Rather than throwing and immediately catching the [FormatException], /// instead use [tryParse] to handle a potential parsing error. /// /// Example: /// ```dart /// var value = int.tryParse(text); /// if (value == null) { /// // handle the problem /// // ... /// } /// ``` external static int parse(String source, {int? radix}); /// Parse [source] as a, possibly signed, integer literal. /// /// Like [parse] except that this function returns `null` where a /// similar call to [parse] would throw a [FormatException]. /// /// Example: /// ```dart /// print(int.tryParse('2021')); // 2021 /// print(int.tryParse('1f')); // null /// // From binary (base 2) value. /// print(int.tryParse('1100', radix: 2)); // 12 /// print(int.tryParse('00011111', radix: 2)); // 31 /// print(int.tryParse('011111100101', radix: 2)); // 2021 /// // From octal (base 8) value. /// print(int.tryParse('14', radix: 8)); // 12 /// print(int.tryParse('37', radix: 8)); // 31 /// print(int.tryParse('3745', radix: 8)); // 2021 /// // From hexadecimal (base 16) value. /// print(int.tryParse('c', radix: 16)); // 12 /// print(int.tryParse('1f', radix: 16)); // 31 /// print(int.tryParse('7e5', radix: 16)); // 2021 /// // From base 35 value. /// print(int.tryParse('y1', radix: 35)); // 1191 == 34 * 35 + 1 /// print(int.tryParse('z1', radix: 35)); // null /// // From base 36 value. /// print(int.tryParse('y1', radix: 36)); // 1225 == 34 * 36 + 1 /// print(int.tryParse('z1', radix: 36)); // 1261 == 35 * 36 + 1 /// ``` external static int? tryParse(String source, {int? radix}); }