// Copyright (c) 2017, 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 arbitrarily large integer value. | |

/// | |

/// Big integers are signed and can have an arbitrary number of | |

/// significant digits, only limited by memory. | |

abstract class BigInt implements Comparable<BigInt> { | |

/// A big integer with the numerical value 0. | |

external static BigInt get zero; | |

/// A big integer with the numerical value 1. | |

external static BigInt get one; | |

/// A big integer with the numerical value 2. | |

external static BigInt get two; | |

/// Parses [source] as a, possibly signed, integer literal and returns 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 literal, which effectively means that the `0x` is ignored | |

/// and the radix is instead set to 16. | |

/// | |

/// For any int `n` and radix `r`, it is guaranteed that | |

/// `n == int.parse(n.toRadixString(r), radix: r)`. | |

/// | |

/// Throws a [FormatException] if the [source] is not a valid integer literal, | |

/// optionally prefixed by a sign. | |

external static BigInt parse(String source, {int? radix}); | |

/// Parses [source] as a, possibly signed, integer literal and returns its | |

/// value. | |

/// | |

/// As [parse] except that this method returns `null` if the input is not | |

/// valid | |

external static BigInt? tryParse(String source, {int? radix}); | |

/// Allocates a big integer from the provided [value] number. | |

external factory BigInt.from(num value); | |

/// Returns the absolute value of this integer. | |

/// | |

/// For any integer `x`, the result is the same as `x < 0 ? -x : x`. | |

BigInt abs(); | |

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

BigInt operator -(); | |

/// Adds [other] to this big integer. | |

/// | |

/// The result is again a big integer. | |

BigInt operator +(BigInt other); | |

/// Subtracts [other] from this big integer. | |

/// | |

/// The result is again a big integer. | |

BigInt operator -(BigInt other); | |

/// Multiplies [other] by this big integer. | |

/// | |

/// The result is again a big integer. | |

BigInt operator *(BigInt other); | |

/// Double division operator. | |

/// | |

/// Matching the similar operator on [int], | |

/// this operation first performs [toDouble] on both this big integer | |

/// and [other], then does [double.operator/] on those values and | |

/// returns the result. | |

/// The initial [toDouble] conversion may lose precision. | |

double operator /(BigInt other); | |

/// Truncating integer division operator. | |

/// | |

/// Performs a truncating integer division, where the remainder is discarded. | |

/// | |

/// The remainder can be computed using the [remainder] method. | |

/// | |

/// Examples: | |

/// ```dart | |

/// var seven = BigInt.from(7); | |

/// var three = BigInt.from(3); | |

/// seven ~/ three; // => 2 | |

/// (-seven) ~/ three; // => -2 | |

/// seven ~/ -three; // => -2 | |

/// seven.remainder(three); // => 1 | |

/// (-seven).remainder(three); // => -1 | |

/// seven.remainder(-three); // => 1 | |

/// ``` | |

BigInt operator ~/(BigInt 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 sign of the returned value `r` is always positive. | |

/// | |

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

BigInt operator %(BigInt other); | |

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

BigInt remainder(BigInt other); | |

/// 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, shiftIndex)`. | |

/// | |

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

BigInt 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, shiftIndex)`. | |

/// | |

/// It is an error if [shiftAmount] is negative. | |

BigInt operator >>(int shiftAmount); | |

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

/// | |

/// Of both operands are negative, the result is negative, otherwise | |

/// the result is non-negative. | |

BigInt operator &(BigInt 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. | |

BigInt operator |(BigInt 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. | |

BigInt operator ^(BigInt 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`. | |

BigInt operator ~(); | |

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

bool operator <(BigInt other); | |

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

bool operator <=(BigInt other); | |

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

bool operator >(BigInt other); | |

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

bool operator >=(BigInt other); | |

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

int compareTo(BigInt other); | |

/// Returns the minimum number of bits required to store this big 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; | |

/// | |

/// BigInt.from(3).bitLength == 2; // 00000011 | |

/// BigInt.from(2).bitLength == 2; // 00000010 | |

/// BigInt.from(1).bitLength == 1; // 00000001 | |

/// BigInt.from(0).bitLength == 0; // 00000000 | |

/// BigInt.from(-1).bitLength == 0; // 11111111 | |

/// BigInt.from(-2).bitLength == 1; // 11111110 | |

/// BigInt.from(-3).bitLength == 2; // 11111101 | |

/// BigInt.from(-4).bitLength == 2; // 11111100 | |

/// ``` | |

int get bitLength; | |

/// Returns the sign of this big integer. | |

/// | |

/// Returns 0 for zero, -1 for values less than zero and | |

/// +1 for values greater than zero. | |

int get sign; | |

/// Whether this big integer is even. | |

bool get isEven; | |

/// Whether this big integer is odd. | |

bool get isOdd; | |

/// Whether this number is negative. | |

bool get isNegative; | |

/// Returns `this` to the power of [exponent]. | |

/// | |

/// Returns [one] if the [exponent] equals 0. | |

/// | |

/// The [exponent] must otherwise be positive. | |

/// | |

/// The result is always equal to the mathematical result of this to the power | |

/// [exponent], only limited by the available memory. | |

BigInt pow(int exponent); | |

/// Returns this integer to the power of [exponent] modulo [modulus]. | |

/// | |

/// The [exponent] must be non-negative and [modulus] must be | |

/// positive. | |

BigInt modPow(BigInt exponent, BigInt modulus); | |

/// Returns the modular multiplicative inverse of this big integer | |

/// modulo [modulus]. | |

/// | |

/// The [modulus] must be positive. | |

/// | |

/// It is an error if no modular inverse exists. | |

// Returns 1/this % modulus, with modulus > 0. | |

BigInt modInverse(BigInt modulus); | |

/// Returns the greatest common divisor of this big 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. | |

BigInt gcd(BigInt other); | |

/// Returns the least significant [width] bits of this big integer as a | |

/// non-negative number (i.e. unsigned representation). The returned value has | |

/// zeros in all bit positions higher than [width]. | |

/// | |

/// ```dart | |

/// BigInt.from(-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); | |

/// ``` | |

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

/// var big15 = BigInt.from(15); | |

/// var big16 = BigInt.from(16); | |

/// var big239 = BigInt.from(239); | |

/// // V--sign bit-V | |

/// big16.toSigned(5) == -big16; // 00010000 -> 11110000 | |

/// big239.toSigned(5) == big15; // 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); | |

/// ``` | |

BigInt toSigned(int width); | |

/// Whether this big integer can be represented as an `int` without losing | |

/// precision. | |

/// | |

/// Warning: this function may give a different result on | |

/// dart2js, dev compiler, and the VM, due to the differences in | |

/// integer precision. | |

bool get isValidInt; | |

/// Returns this [BigInt] as an [int]. | |

/// | |

/// If the number does not fit, clamps to the max (or min) | |

/// integer. | |

/// | |

/// Warning: the clamping behaves differently on dart2js, dev | |

/// compiler, and the VM, due to the differences in integer | |

/// precision. | |

int toInt(); | |

/// Returns this [BigInt] 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 String-representation of this integer. | |

/// | |

/// The returned string is parsable by [parse]. | |

/// For any `BigInt` `i`, it is guaranteed that | |

/// `i == BigInt.parse(i.toString())`. | |

String toString(); | |

/// Converts [this] 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 an 'z' being 35. | |

/// | |

/// The [radix] argument must be an integer in the range 2 to 36. | |

String toRadixString(int radix); | |

} |