// Copyright 2012 Google Inc. All Rights Reserved.

#include "vm/bigint_operations.h"

#include "platform/utils.h"

#include "vm/double_internals.h"
#include "vm/exceptions.h"
#include "vm/object_store.h"
#include "vm/zone.h"

namespace dart {

RawBigint* BigintOperations::NewFromSmi(const Smi& smi, Heap::Space space) {
  intptr_t value = smi.Value();
  if (value == 0) {
    return Zero();
  }

  bool is_negative = (value < 0);
  if (is_negative) {
    value = -value;
  }
  // Assert that there are no overflows. Smis reserve a bit for themselves, but
  // protect against future changes.
  ASSERT(-Smi::kMinValue > 0);

  // A single digit of a Bigint might not be sufficient to store a Smi.
  // Count number of needed Digits.
  intptr_t digit_count = 0;
  intptr_t count_value = value;
  while (count_value > 0) {
    digit_count++;
    count_value >>= kDigitBitSize;
  }

  // Allocate a bigint of the correct size and copy the bits.
  const Bigint& result = Bigint::Handle(Bigint::Allocate(digit_count, space));
  for (int i = 0; i < digit_count; i++) {
    result.SetChunkAt(i, static_cast<Chunk>(value & kDigitMask));
    value >>= kDigitBitSize;
  }
  result.SetSign(is_negative);
  ASSERT(IsClamped(result));
  return result.raw();
}


RawBigint* BigintOperations::NewFromInt64(int64_t value, Heap::Space space) {
  bool is_negative = value < 0;

  if (is_negative) {
    value = -value;
  }

  const Bigint& result = Bigint::Handle(NewFromUint64(value, space));
  result.SetSign(is_negative);

  return result.raw();
}


RawBigint* BigintOperations::NewFromUint64(uint64_t value, Heap::Space space) {
  if (value == 0) {
    return Zero();
  }
  // A single digit of a Bigint might not be sufficient to store the value.
  // Count number of needed Digits.
  intptr_t digit_count = 0;
  uint64_t count_value = value;
  while (count_value > 0) {
    digit_count++;
    count_value >>= kDigitBitSize;
  }

  // Allocate a bigint of the correct size and copy the bits.
  const Bigint& result = Bigint::Handle(Bigint::Allocate(digit_count, space));
  for (int i = 0; i < digit_count; i++) {
    result.SetChunkAt(i, static_cast<Chunk>(value & kDigitMask));
    value >>= kDigitBitSize;
  }
  result.SetSign(false);
  ASSERT(IsClamped(result));
  return result.raw();
}


RawBigint* BigintOperations::NewFromCString(const char* str,
                                            Heap::Space space) {
  ASSERT(str != NULL);
  if (str[0] == '\0') {
    return Zero();
  }

  // If the string starts with '-' recursively restart the whole operation
  // without the character and then toggle the sign.
  // This allows multiple leading '-' (which will cancel each other out), but
  // we have added an assert, to make sure that the returned result of the
  // recursive call is not negative.
  // We don't catch leading '-'s for zero. Ex: "--0", or "---".
  if (str[0] == '-') {
    const Bigint& result = Bigint::Handle(NewFromCString(&str[1], space));
    result.ToggleSign();
    ASSERT(result.IsZero() || result.IsNegative());
    ASSERT(IsClamped(result));
    return result.raw();
  }

  intptr_t str_length = strlen(str);
  if ((str_length > 2) &&
      (str[0] == '0') &&
      ((str[1] == 'x') || (str[1] == 'X'))) {
    const Bigint& result = Bigint::Handle(FromHexCString(&str[2], space));
    ASSERT(IsClamped(result));
    return result.raw();
  } else {
    return FromDecimalCString(str, space);
  }
}


intptr_t BigintOperations::ComputeChunkLength(const char* hex_string) {
  ASSERT(kDigitBitSize % 4 == 0);
  intptr_t hex_length = strlen(hex_string);
  // Round up.
  intptr_t bigint_length = ((hex_length - 1) / kHexCharsPerDigit) + 1;
  return bigint_length;
}


RawBigint* BigintOperations::FromHexCString(const char* hex_string,
                                            Heap::Space space) {
  // If the string starts with '-' recursively restart the whole operation
  // without the character and then toggle the sign.
  // This allows multiple leading '-' (which will cancel each other out), but
  // we have added an assert, to make sure that the returned result of the
  // recursive call is not negative.
  // We don't catch leading '-'s for zero. Ex: "--0", or "---".
  if (hex_string[0] == '-') {
    const Bigint& value = Bigint::Handle(FromHexCString(&hex_string[1], space));
    value.ToggleSign();
    ASSERT(value.IsZero() || value.IsNegative());
    ASSERT(IsClamped(value));
    return value.raw();
  }
  intptr_t bigint_length = ComputeChunkLength(hex_string);
  const Bigint& result = Bigint::Handle(Bigint::Allocate(bigint_length, space));
  FromHexCString(hex_string, result);
  return result.raw();
}


RawBigint* BigintOperations::FromDecimalCString(const char* str,
                                                Heap::Space space) {
  // Read 8 digits a time. 10^8 < 2^27.
  const int kDigitsPerIteration = 8;
  const Chunk kTenMultiplier = 100000000;
  ASSERT(kDigitBitSize >= 27);

  intptr_t str_length = strlen(str);
  intptr_t str_pos = 0;

  // Read first digit separately. This avoids a multiplication and addition.
  // The first digit might also not have kDigitsPerIteration decimal digits.
  int first_digit_decimal_digits = str_length % kDigitsPerIteration;
  Chunk digit = 0;
  for (intptr_t i = 0; i < first_digit_decimal_digits; i++) {
    char c = str[str_pos++];
    ASSERT(('0' <= c) && (c <= '9'));
    digit = digit * 10 + c - '0';
  }
  Bigint& result = Bigint::Handle(Bigint::Allocate(1));
  result.SetChunkAt(0, digit);
  Clamp(result);  // Multiplication requires the inputs to be clamped.

  // Read kDigitsPerIteration at a time, and store it in 'increment'.
  // Then multiply the temporary result by 10^kDigitsPerIteration and add
  // 'increment' to the new result.
  const Bigint& increment = Bigint::Handle(Bigint::Allocate(1));
  while (str_pos < str_length - 1) {
    Chunk digit = 0;
    for (intptr_t i = 0; i < kDigitsPerIteration; i++) {
      char c = str[str_pos++];
      ASSERT(('0' <= c) && (c <= '9'));
      digit = digit * 10 + c - '0';
    }
    result ^= MultiplyWithDigit(result, kTenMultiplier);
    if (digit != 0) {
      increment.SetChunkAt(0, digit);
      result ^= Add(result, increment);
    }
  }
  Clamp(result);
  if ((space == Heap::kOld) && !result.IsOld()) {
    result ^= Object::Clone(result, Heap::kOld);
  }
  return result.raw();
}


RawBigint* BigintOperations::NewFromDouble(double d, Heap::Space space) {
  if ((-1.0 < d) && (d < 1.0)) {
    // Shortcut for small numbers. Also makes the right-shift below
    // well specified.
    Smi& zero = Smi::Handle(Smi::New(0));
    return NewFromSmi(zero, space);
  }
  DoubleInternals internals = DoubleInternals(d);
  if (internals.IsSpecial()) {
    GrowableArray<const Object*> exception_arguments;
    exception_arguments.Add(
        &Object::ZoneHandle(String::New("BigintOperations::NewFromDouble")));
    Exceptions::ThrowByType(Exceptions::kInternalError, exception_arguments);
  }
  uint64_t significand = internals.Significand();
  int exponent = internals.Exponent();
  int sign = internals.Sign();
  if (exponent <= 0) {
    significand >>= -exponent;
    exponent = 0;
  } else if (exponent <= 10) {
    // A double significand has at most 53 bits. The following shift will
    // hence not overflow, and yield an integer of at most 63 bits.
    significand <<= exponent;
    exponent = 0;
  }
  // A significand has at most 63 bits (after the shift above).
  // The cast to int64_t is hence safe.
  const Bigint& result =
      Bigint::Handle(NewFromInt64(static_cast<int64_t>(significand), space));
  result.SetSign(sign < 0);
  if (exponent > 0) {
    return ShiftLeft(result, exponent);
  } else {
    return result.raw();
  }
}


const char* BigintOperations::ToHexCString(intptr_t length,
                                           bool is_negative,
                                           void* data,
                                           uword (*allocator)(intptr_t size)) {
  NoGCScope no_gc;

  ASSERT(kDigitBitSize % 4 == 0);

  intptr_t chunk_length = length;
  Chunk* chunk_data = reinterpret_cast<Chunk*>(data);
  if (length == 0) {
    const char* zero = "0x0";
    const int kLength = strlen(zero);
    char* result = reinterpret_cast<char*>(allocator(kLength + 1));
    ASSERT(result != NULL);
    memmove(result, zero, kLength);
    result[kLength] = '\0';
    return result;
  }
  ASSERT(chunk_data != NULL);

  // Compute the number of hex-digits that are needed to represent the
  // leading bigint-digit. All other digits need exactly kHexCharsPerDigit
  // characters.
  int leading_hex_digits = 0;
  Chunk leading_digit = chunk_data[chunk_length - 1];
  while (leading_digit != 0) {
    leading_hex_digits++;
    leading_digit >>= 4;
  }
  // Sum up the space that is needed for the string-representation.
  intptr_t required_size = 0;
  if (is_negative) {
    required_size++;  // For the leading "-".
  }
  required_size += 2;  // For the "0x".
  required_size += leading_hex_digits;
  required_size += (chunk_length - 1) * kHexCharsPerDigit;
  required_size++;  // For the trailing '\0'.
  char* result = reinterpret_cast<char*>(allocator(required_size));
  // Print the number into the string.
  // Start from the last position.
  intptr_t pos = required_size - 1;
  result[pos--] = '\0';
  for (intptr_t i = 0; i < (chunk_length - 1); i++) {
    // Print all non-leading characters (which are printed with
    // kHexCharsPerDigit characters.
    Chunk digit = chunk_data[i];
    for (int j = 0; j < kHexCharsPerDigit; j++) {
      result[pos--] = Utils::IntToHexDigit(static_cast<int>(digit & 0xF));
      digit >>= 4;
    }
  }
  // Print the leading digit.
  leading_digit = chunk_data[chunk_length - 1];
  while (leading_digit != 0) {
    result[pos--] = Utils::IntToHexDigit(static_cast<int>(leading_digit & 0xF));
    leading_digit >>= 4;
  }
  result[pos--] = 'x';
  result[pos--] = '0';
  if (is_negative) {
    result[pos--] = '-';
  }
  ASSERT(pos == -1);
  return result;
}


const char* BigintOperations::ToHexCString(const Bigint& bigint,
                                           uword (*allocator)(intptr_t size)) {
  NoGCScope no_gc;

  intptr_t length = bigint.Length();
  return ToHexCString(length,
                      bigint.IsNegative(),
                      length ? bigint.ChunkAddr(0) : NULL,
                      allocator);
}


const char* BigintOperations::ToDecimalCString(
    const Bigint& bigint, uword (*allocator)(intptr_t size)) {
  // log10(2) ~= 0.30102999566398114.
  const intptr_t kLog2Dividend = 30103;
  const intptr_t kLog2Divisor = 100000;
  // We remove a small constant for rounding imprecision, the \0 character and
  // the negative sign.
  const intptr_t kMaxAllowedDigitLength =
      (kIntptrMax - 10) / kLog2Dividend / kDigitBitSize * kLog2Divisor;

  intptr_t length = bigint.Length();
  if (length >= kMaxAllowedDigitLength) {
    // Use the preallocated out of memory exception to avoid calling
    // into dart code or allocating any code.
    Isolate* isolate = Isolate::Current();
    const Instance& exception =
        Instance::Handle(isolate->object_store()->out_of_memory());
    Exceptions::Throw(exception);
    UNREACHABLE();
  }

  // Approximate the size of the resulting string. We prefer overestimating
  // to not allocating enough.
  int64_t bit_length = length * kDigitBitSize;
  ASSERT(bit_length > length);
  int64_t decimal_length = (bit_length * kLog2Dividend / kLog2Divisor) + 1;
  // Add one byte for the trailing \0 character.
  int64_t required_size = decimal_length + 1;
  if (bigint.IsNegative()) {
    required_size++;
  }
  ASSERT(required_size == static_cast<intptr_t>(required_size));
  // We will fill the result in the inverse order and then exchange at the end.
  char* result =
      reinterpret_cast<char*>(allocator(static_cast<intptr_t>(required_size)));
  ASSERT(result != NULL);
  int result_pos = 0;

  // We divide the input into pieces of ~27 bits which can be efficiently
  // handled.
  const intptr_t kChunkDivisor = 100000000;
  const int kChunkDigits = 8;
  ASSERT(pow(10.0, kChunkDigits) == kChunkDivisor);
  ASSERT(static_cast<Chunk>(kChunkDivisor) < kDigitMaxValue);
  ASSERT(Smi::IsValid(kChunkDivisor));
  const Bigint& divisor = Bigint::Handle(NewFromInt64(kChunkDivisor));

  // Rest contains the remaining bigint that needs to be printed.
  Bigint& rest = Bigint::Handle(bigint.raw());
  Bigint& quotient = Bigint::Handle();
  Bigint& remainder = Bigint::Handle();
  while (!rest.IsZero()) {
    DivideRemainder(rest, divisor, &quotient, &remainder);
    ASSERT(remainder.Length() <= 1);
    intptr_t part = (remainder.Length() == 1)
        ? static_cast<intptr_t>(remainder.GetChunkAt(0))
        : 0;
    for (int i = 0; i < kChunkDigits; i++) {
      result[result_pos++] = '0' + (part % 10);
      part /= 10;
    }
    ASSERT(part == 0);
    rest = quotient.raw();
  }
  // Move the resulting position back until we don't have any zeroes anymore.
  // This is done so that we can remove all leading zeroes.
  while (result_pos > 1 && result[result_pos - 1] == '0') {
    result_pos--;
  }
  if (bigint.IsNegative()) {
    result[result_pos++] = '-';
  }
  // Reverse the string.
  int i = 0;
  int j = result_pos - 1;
  while (i < j) {
    char tmp = result[i];
    result[i] = result[j];
    result[j] = tmp;
    i++;
    j--;
  }
  ASSERT(result_pos >= 0);
  result[result_pos] = '\0';
  return result;
}


bool BigintOperations::FitsIntoSmi(const Bigint& bigint) {
  intptr_t bigint_length = bigint.Length();
  if (bigint_length == 0) {
    return true;
  }
  if ((bigint_length == 1) &&
      (static_cast<size_t>(kDigitBitSize) <
       (sizeof(intptr_t) * kBitsPerByte))) {
    return true;
  }

  uintptr_t limit;
  if (bigint.IsNegative()) {
    limit = static_cast<uintptr_t>(-Smi::kMinValue);
  } else {
    limit = static_cast<uintptr_t>(Smi::kMaxValue);
  }
  bool bigint_is_greater = false;
  // Consume the least-significant digits of the bigint.
  // If bigint_is_greater is set, then the processed sub-part of the bigint is
  // greater than the corresponding part of the limit.
  for (int i = 0; i < bigint_length - 1; i++) {
    Chunk limit_digit = static_cast<Chunk>(limit & kDigitMask);
    Chunk bigint_digit = bigint.GetChunkAt(i);
    if (limit_digit < bigint_digit) {
      bigint_is_greater = true;
    } else if (limit_digit > bigint_digit) {
      bigint_is_greater = false;
    }  // else don't change the boolean.
    limit >>= kDigitBitSize;

    // Bail out if the bigint is definitely too big.
    if (limit == 0) {
      return false;
    }
  }
  Chunk most_significant_digit = bigint.GetChunkAt(bigint_length - 1);
  if (limit > most_significant_digit) {
    return true;
  }
  if (limit < most_significant_digit) {
    return false;
  }
  return !bigint_is_greater;
}


RawSmi* BigintOperations::ToSmi(const Bigint& bigint) {
  ASSERT(FitsIntoSmi(bigint));
  intptr_t value = 0;
  for (int i = bigint.Length() - 1; i >= 0; i--) {
    value <<= kDigitBitSize;
    value += static_cast<intptr_t>(bigint.GetChunkAt(i));
  }
  if (bigint.IsNegative()) {
    value = -value;
  }
  return Smi::New(value);
}


RawDouble* BigintOperations::ToDouble(const Bigint& bigint) {
  ASSERT(IsClamped(bigint));
  if (bigint.IsZero()) {
    return Double::New(0.0);
  }
  if (AbsFitsIntoUint64(bigint)) {
    double absolute_value = static_cast<double>(AbsToUint64(bigint));
    double result = bigint.IsNegative() ? -absolute_value : absolute_value;
    return Double::New(result);
  }

  static const int kPhysicalSignificandSize = 52;
  // The significand size has an additional hidden bit.
  static const int kSignificandSize = kPhysicalSignificandSize + 1;
  static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
  static const int kMaxExponent = 0x7FF - kExponentBias;
  static const uint64_t kOne64 = 1;
  static const uint64_t kInfinityBits =
      DART_2PART_UINT64_C(0x7FF00000, 00000000);

  // A double is composed of an exponent e and a significand s. Its value equals
  // s * 2^e. The significand has 53 bits of which the first one must always be
  // 1 (at least for then numbers we are working with here) and is therefore
  // omitted. The physical size of the significand is thus 52 bits.
  // The exponent has 11 bits and is biased by 0x3FF + 52. For example an
  // exponent e = 10 is written as 0x3FF + 52 + 10 (in the 11 bits that are
  // reserved for the exponent).
  // When converting the given bignum to a double we have to pay attention to
  // the rounding. In particular we have to decide which double to pick if an
  // input lies exactly between two doubles. As usual with double operations
  // we pick the double with an even significand in such cases.
  //
  // General approach of this algorithm: Get 54 bits (one more than the
  // significand size) of the bigint. If the last bit is then 1, then (without
  // knowledge of the remaining bits) we could have a half-way number.
  // If the second-to-last bit is odd then we know that we have to round up:
  // if the remaining bits are not zero then the input lies closer to the higher
  // double. If the remaining bits are zero then we have a half-way case and
  // we need to round up too (rounding to the even double).
  // If the second-to-last bit is even then we need to look at the remaining
  // bits to determine if any of them is not zero. If that's the case then the
  // number lies closer to the next-higher double. Otherwise we round the
  // half-way case down to even.

  intptr_t length = bigint.Length();
  if (((length - 1) * kDigitBitSize) > (kMaxExponent + kSignificandSize)) {
    // Does not fit into a double.
    double infinity = bit_cast<double>(kInfinityBits);
    return Double::New(bigint.IsNegative() ? -infinity : infinity);
  }


  intptr_t digit_index = length - 1;
  // In order to round correctly we need to look at half-way cases. Therefore we
  // get kSignificandSize + 1 bits. If the last bit is 1 then we have to look
  // at the remaining bits to know if we have to round up.
  int needed_bits = kSignificandSize + 1;
  ASSERT((kDigitBitSize < needed_bits) && (2 * kDigitBitSize >= needed_bits));
  bool discarded_bits_were_zero = true;

  Chunk firstDigit = bigint.GetChunkAt(digit_index--);
  uint64_t twice_significand_floor = firstDigit;
  intptr_t twice_significant_exponent = (digit_index + 1) * kDigitBitSize;
  needed_bits -= CountBits(firstDigit);

  if (needed_bits >= kDigitBitSize) {
    twice_significand_floor <<= kDigitBitSize;
    twice_significand_floor |= bigint.GetChunkAt(digit_index--);
    twice_significant_exponent -= kDigitBitSize;
    needed_bits -= kDigitBitSize;
  }
  if (needed_bits > 0) {
    ASSERT(needed_bits <= kDigitBitSize);
    Chunk digit = bigint.GetChunkAt(digit_index--);
    int discarded_bits_count = kDigitBitSize - needed_bits;
    twice_significand_floor <<= needed_bits;
    twice_significand_floor |= digit >> discarded_bits_count;
    twice_significant_exponent -= needed_bits;
    uint64_t discarded_bits_mask = (kOne64 << discarded_bits_count) - 1;
    discarded_bits_were_zero = ((digit & discarded_bits_mask) == 0);
  }
  ASSERT((twice_significand_floor >> kSignificandSize) == 1);

  // We might need to round up the significand later.
  uint64_t significand = twice_significand_floor >> 1;
  intptr_t exponent = twice_significant_exponent + 1;

  if (exponent >= kMaxExponent) {
    // Infinity.
    // Does not fit into a double.
    double infinity = bit_cast<double>(kInfinityBits);
    return Double::New(bigint.IsNegative() ? -infinity : infinity);
  }

  if ((twice_significand_floor & 1) == 1) {
    bool round_up = false;

    if ((significand & 1) != 0 || !discarded_bits_were_zero) {
      // Even if the remaining bits are zero we still need to round up since we
      // want to round to even for half-way cases.
      round_up = true;
    } else {
      // Could be a half-way case. See if the remaining bits are non-zero.
      for (intptr_t i = 0; i <= digit_index; i++) {
        if (bigint.GetChunkAt(i) != 0) {
          round_up = true;
          break;
        }
      }
    }

    if (round_up) {
      significand++;
      // It might be that we just went from 53 bits to 54 bits.
      // Example: After adding 1 to 1FFF..FF (with 53 bits set to 1) we have
      // 2000..00 (= 2 ^ 54). When adding the exponent and significand together
      // this will increase the exponent by 1 which is exactly what we want.
    }
  }

  ASSERT((significand >> (kSignificandSize - 1)) == 1
         || significand == kOne64 << kSignificandSize);
  uint64_t biased_exponent = exponent + kExponentBias;
  // The significand still has the hidden bit. We simply decrement the biased
  // exponent by one instead of playing around with the significand.
  biased_exponent--;
  // Note that we must use the plus operator instead of bit-or.
  uint64_t double_bits =
      (biased_exponent << kPhysicalSignificandSize) + significand;

  double value = bit_cast<double>(double_bits);
  if (bigint.IsNegative()) {
    value = -value;
  }
  return Double::New(value);
}


bool BigintOperations::FitsIntoMint(const Bigint& bigint) {
  intptr_t bigint_length = bigint.Length();
  if (bigint_length == 0) {
    return true;
  }
  if ((bigint_length < 3) &&
      (static_cast<size_t>(kDigitBitSize) <
       (sizeof(intptr_t) * kBitsPerByte))) {
    return true;
  }

  uint64_t limit;
  if (bigint.IsNegative()) {
    limit = static_cast<uint64_t>(Mint::kMinValue);
  } else {
    limit = static_cast<uint64_t>(Mint::kMaxValue);
  }
  bool bigint_is_greater = false;
  // Consume the least-significant digits of the bigint.
  // If bigint_is_greater is set, then the processed sub-part of the bigint is
  // greater than the corresponding part of the limit.
  for (int i = 0; i < bigint_length - 1; i++) {
    Chunk limit_digit = static_cast<Chunk>(limit & kDigitMask);
    Chunk bigint_digit = bigint.GetChunkAt(i);
    if (limit_digit < bigint_digit) {
      bigint_is_greater = true;
    } else if (limit_digit > bigint_digit) {
      bigint_is_greater = false;
    }  // else don't change the boolean.
    limit >>= kDigitBitSize;

    // Bail out if the bigint is definitely too big.
    if (limit == 0) {
      return false;
    }
  }
  Chunk most_significant_digit = bigint.GetChunkAt(bigint_length - 1);
  if (limit > most_significant_digit) {
    return true;
  }
  if (limit < most_significant_digit) {
    return false;
  }
  return !bigint_is_greater;
}


uint64_t BigintOperations::AbsToUint64(const Bigint& bigint) {
  ASSERT(AbsFitsIntoUint64(bigint));
  uint64_t value = 0;
  for (int i = bigint.Length() - 1; i >= 0; i--) {
    value <<= kDigitBitSize;
    value += static_cast<intptr_t>(bigint.GetChunkAt(i));
  }
  return value;
}


int64_t BigintOperations::ToMint(const Bigint& bigint) {
  ASSERT(FitsIntoMint(bigint));
  int64_t value = AbsToUint64(bigint);
  if (bigint.IsNegative()) {
    value = -value;
  }
  return value;
}


bool BigintOperations::AbsFitsIntoUint64(const Bigint& bigint) {
  intptr_t b_length = bigint.Length();
  int num_bits = CountBits(bigint.GetChunkAt(b_length - 1));
  num_bits += (kDigitBitSize * (b_length - 1));
  if (num_bits > 64) return false;
  return true;
}


bool BigintOperations::FitsIntoUint64(const Bigint& bigint) {
  if (bigint.IsNegative()) return false;
  return AbsFitsIntoUint64(bigint);
}


uint64_t BigintOperations::ToUint64(const Bigint& bigint) {
  ASSERT(FitsIntoUint64(bigint));
  return AbsToUint64(bigint);
}


RawBigint* BigintOperations::Multiply(const Bigint& a, const Bigint& b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));

  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();
  intptr_t result_length = a_length + b_length;
  const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));

  if (a.IsNegative() != b.IsNegative()) {
    result.ToggleSign();
  }

  // Comba multiplication: compute each column separately.
  // Example: r = a2a1a0 * b2b1b0.
  //    r =  1    * a0b0 +
  //        10    * (a1b0 + a0b1) +
  //        100   * (a2b0 + a1b1 + a0b2) +
  //        1000  * (a2b1 + a1b2) +
  //        10000 * a2b2
  //
  // Each column will be accumulated in an integer of type DoubleChunk. We
  // must guarantee that the column-sum will not overflow.
  //
  // In the worst case we have to accumulate k = Min(a.length, b.length)
  // products plus the carry from the previous round.
  // Each bigint-digit is smaller than beta = 2^kDigitBitSize.
  // Each product is at most (beta - 1)^2.
  // If we want to use Comba multiplication the following condition must hold:
  // k * (beta - 1)^2 + (2^(kDoubleChunkBitSize - kDigitBitSize) - 1) <
  //        2^kDoubleChunkBitSize.
  const DoubleChunk square =
      static_cast<DoubleChunk>(kDigitMaxValue) * kDigitMaxValue;
  const DoubleChunk kDoubleChunkMaxValue = static_cast<DoubleChunk>(-1);
  const DoubleChunk left_over_carry = kDoubleChunkMaxValue >> kDigitBitSize;
  const intptr_t kMaxDigits = (kDoubleChunkMaxValue - left_over_carry) / square;
  if (Utils::Minimum(a_length, b_length) > kMaxDigits) {
    UNIMPLEMENTED();
  }

  DoubleChunk accumulator = 0;  // Accumulates the result of one column.
  for (intptr_t i = 0; i < result_length; i++) {
    // Example: r = a2a1a0 * b2b1b0.
    //   For i == 0, compute a0b0.
    //       i == 1,         a1b0 + a0b1 + overflow from i == 0.
    //       i == 2,         a2b0 + a1b1 + a0b2 + overflow from i == 1.
    //       ...
    // The indices into a and b are such that their sum equals i.
    intptr_t a_index = Utils::Minimum(a_length - 1, i);
    intptr_t b_index = i - a_index;
    ASSERT(a_index + b_index == i);

    // Instead of testing for a_index >= 0 && b_index < b_length we compute the
    // number of iterations first.
    intptr_t iterations = Utils::Minimum(b_length - b_index, a_index + 1);
    for (intptr_t j = 0; j < iterations; j++) {
      DoubleChunk chunk_a = a.GetChunkAt(a_index);
      DoubleChunk chunk_b = b.GetChunkAt(b_index);
      accumulator += chunk_a * chunk_b;
      a_index--;
      b_index++;
    }
    result.SetChunkAt(i, static_cast<Chunk>(accumulator & kDigitMask));
    accumulator >>= kDigitBitSize;
  }
  ASSERT(accumulator == 0);

  Clamp(result);
  return result.raw();
}


RawBigint* BigintOperations::Divide(const Bigint& a, const Bigint& b) {
  Bigint& quotient = Bigint::Handle();
  Bigint& remainder = Bigint::Handle();
  DivideRemainder(a, b, &quotient, &remainder);
  return quotient.raw();
}


RawBigint* BigintOperations::Modulo(const Bigint& a, const Bigint& b) {
  Bigint& quotient = Bigint::Handle();
  Bigint& remainder = Bigint::Handle();
  DivideRemainder(a, b, &quotient, &remainder);
  // Emulating code in Integer::ArithmeticOp (Euclidian modulo).
  if (remainder.IsNegative()) {
    if (b.IsNegative()) {
      return BigintOperations::Subtract(remainder, b);
    } else {
      return BigintOperations::Add(remainder, b);
    }
  }
  return remainder.raw();
}


RawBigint* BigintOperations::Remainder(const Bigint& a, const Bigint& b) {
  Bigint& quotient = Bigint::Handle();
  Bigint& remainder = Bigint::Handle();
  DivideRemainder(a, b, &quotient, &remainder);
  return remainder.raw();
}


RawBigint* BigintOperations::ShiftLeft(const Bigint& bigint, intptr_t amount) {
  ASSERT(IsClamped(bigint));
  ASSERT(amount >= 0);
  intptr_t bigint_length = bigint.Length();
  if (bigint.IsZero()) {
    return Zero();
  }
  // TODO(floitsch): can we reuse the input?
  if (amount == 0) {
    return Copy(bigint);
  }
  intptr_t digit_shift = amount / kDigitBitSize;
  intptr_t bit_shift = amount % kDigitBitSize;
  if (bit_shift == 0) {
    const Bigint& result =
        Bigint::Handle(Bigint::Allocate(bigint_length + digit_shift));
    for (intptr_t i = 0; i < digit_shift; i++) {
      result.SetChunkAt(i, 0);
    }
    for (intptr_t i = 0; i < bigint_length; i++) {
      result.SetChunkAt(i + digit_shift, bigint.GetChunkAt(i));
    }
    if (bigint.IsNegative()) {
      result.ToggleSign();
    }
    return result.raw();
  } else {
    const Bigint& result =
        Bigint::Handle(Bigint::Allocate(bigint_length + digit_shift + 1));
    for (intptr_t i = 0; i < digit_shift; i++) {
      result.SetChunkAt(i, 0);
    }
    Chunk carry = 0;
    for (intptr_t i = 0; i < bigint_length; i++) {
      Chunk digit = bigint.GetChunkAt(i);
      Chunk shifted_digit = ((digit << bit_shift) & kDigitMask) + carry;
      result.SetChunkAt(i + digit_shift, shifted_digit);
      carry = digit >> (kDigitBitSize - bit_shift);
    }
    result.SetChunkAt(bigint_length + digit_shift, carry);
    if (bigint.IsNegative()) {
      result.ToggleSign();
    }
    Clamp(result);
    return result.raw();
  }
}


RawBigint* BigintOperations::ShiftRight(const Bigint& bigint, intptr_t amount) {
  ASSERT(IsClamped(bigint));
  ASSERT(amount >= 0);
  intptr_t bigint_length = bigint.Length();
  if (bigint.IsZero()) {
    return Zero();
  }
  // TODO(floitsch): can we reuse the input?
  if (amount == 0) {
    return Copy(bigint);
  }
  intptr_t digit_shift = amount / kDigitBitSize;
  intptr_t bit_shift = amount % kDigitBitSize;
  if (digit_shift >= bigint_length) {
    return bigint.IsNegative() ? MinusOne() : Zero();
  }

  const Bigint& result =
      Bigint::Handle(Bigint::Allocate(bigint_length - digit_shift));
  if (bit_shift == 0) {
    for (intptr_t i = 0; i < bigint_length - digit_shift; i++) {
      result.SetChunkAt(i, bigint.GetChunkAt(i + digit_shift));
    }
  } else {
    Chunk carry = 0;
    for (intptr_t i = bigint_length - 1; i >= digit_shift; i--) {
      Chunk digit = bigint.GetChunkAt(i);
      Chunk shifted_digit = (digit >> bit_shift) + carry;
      result.SetChunkAt(i - digit_shift, shifted_digit);
      carry = (digit << (kDigitBitSize - bit_shift)) & kDigitMask;
    }
    Clamp(result);
  }

  if (bigint.IsNegative()) {
    result.ToggleSign();
    // If the input is negative then the result needs to be rounded down.
    // Example: -5 >> 2 => -2
    bool needs_rounding = false;
    for (intptr_t i = 0; i < digit_shift; i++) {
      if (bigint.GetChunkAt(i) != 0) {
        needs_rounding = true;
        break;
      }
    }
    if (!needs_rounding && (bit_shift > 0)) {
      Chunk digit = bigint.GetChunkAt(digit_shift);
      needs_rounding = (digit << (kChunkBitSize - bit_shift)) != 0;
    }
    if (needs_rounding) {
      Bigint& one = Bigint::Handle(One());
      return Subtract(result, one);
    }
  }

  return result.raw();
}


RawBigint* BigintOperations::BitAnd(const Bigint& a, const Bigint& b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));

  if (a.IsZero() || b.IsZero()) {
    return Zero();
  }
  if (a.IsNegative() && !b.IsNegative()) {
    return BitAnd(b, a);
  }
  if ((a.IsNegative() == b.IsNegative()) && (a.Length() < b.Length())) {
    return BitAnd(b, a);
  }

  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();
  intptr_t min_length = Utils::Minimum(a_length, b_length);
  intptr_t max_length = Utils::Maximum(a_length, b_length);
  if (!b.IsNegative()) {
    ASSERT(!a.IsNegative());
    intptr_t result_length = min_length;
    const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));

    for (intptr_t i = 0; i < min_length; i++) {
      result.SetChunkAt(i, a.GetChunkAt(i) & b.GetChunkAt(i));
    }
    Clamp(result);
    return result.raw();
  }

  // Bigints encode negative values by storing the absolute value and the sign
  // separately. To do bit operations we need to simulate numbers that are
  // implemented as two's complement.
  // The negation of a positive number x would be encoded as follows in
  // two's complement: n = ~(x - 1).
  // The inverse transformation is hence (~n) + 1.

  if (!a.IsNegative()) {
    ASSERT(b.IsNegative());
    // The result will be positive.
    intptr_t result_length = a_length;
    const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
    Chunk borrow = 1;
    for (intptr_t i = 0; i < min_length; i++) {
      Chunk b_digit = b.GetChunkAt(i) - borrow;
      result.SetChunkAt(i, a.GetChunkAt(i) & (~b_digit) & kDigitMask);
      borrow = b_digit >> (kChunkBitSize - 1);
    }
    for (intptr_t i = min_length; i < a_length; i++) {
      result.SetChunkAt(i, a.GetChunkAt(i) & (kDigitMaxValue - borrow));
      borrow = 0;
    }
    Clamp(result);
    return result.raw();
  }

  ASSERT(a.IsNegative());
  ASSERT(b.IsNegative());
  // The result will be negative.
  // We need to convert a and b to two's complement. Do the bit-operation there,
  // and transform the resulting bits from two's complement back to separated
  // magnitude and sign.
  // a & b is therefore computed as ~((~(a - 1)) & (~(b - 1))) + 1 which is
  //   equal to ((a-1) | (b-1)) + 1.
  intptr_t result_length = max_length + 1;
  const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
  result.ToggleSign();
  Chunk a_borrow = 1;
  Chunk b_borrow = 1;
  Chunk result_carry = 1;
  ASSERT(a_length >= b_length);
  for (intptr_t i = 0; i < b_length; i++) {
    Chunk a_digit = a.GetChunkAt(i) - a_borrow;
    Chunk b_digit = b.GetChunkAt(i) - b_borrow;
    Chunk result_chunk = ((a_digit | b_digit) & kDigitMask) + result_carry;
    result.SetChunkAt(i, result_chunk & kDigitMask);
    a_borrow = a_digit >> (kChunkBitSize - 1);
    b_borrow = b_digit >> (kChunkBitSize - 1);
    result_carry = result_chunk >> kDigitBitSize;
  }
  for (intptr_t i = b_length; i < a_length; i++) {
    Chunk a_digit = a.GetChunkAt(i) - a_borrow;
    Chunk b_digit = -b_borrow;
    Chunk result_chunk = ((a_digit | b_digit) & kDigitMask) + result_carry;
    result.SetChunkAt(i, result_chunk & kDigitMask);
    a_borrow = a_digit >> (kChunkBitSize - 1);
    b_borrow = 0;
    result_carry = result_chunk >> kDigitBitSize;
  }
  Chunk a_digit = -a_borrow;
  Chunk b_digit = -b_borrow;
  Chunk result_chunk = ((a_digit | b_digit) & kDigitMask) + result_carry;
  result.SetChunkAt(a_length, result_chunk & kDigitMask);
  Clamp(result);
  return result.raw();
}


RawBigint* BigintOperations::BitOr(const Bigint& a, const Bigint& b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));

  if (a.IsNegative() && !b.IsNegative()) {
    return BitOr(b, a);
  }
  if ((a.IsNegative() == b.IsNegative()) && (a.Length() < b.Length())) {
    return BitOr(b, a);
  }

  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();
  intptr_t min_length = Utils::Minimum(a_length, b_length);
  intptr_t max_length = Utils::Maximum(a_length, b_length);
  if (!b.IsNegative()) {
    ASSERT(!a.IsNegative());
    intptr_t result_length = max_length;
    const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));

    ASSERT(a_length >= b_length);
    for (intptr_t i = 0; i < b_length; i++) {
      result.SetChunkAt(i, a.GetChunkAt(i) | b.GetChunkAt(i));
    }
    for (intptr_t i = b_length; i < a_length; i++) {
      result.SetChunkAt(i, a.GetChunkAt(i));
    }
    return result.raw();
  }

  // Bigints encode negative values by storing the absolute value and the sign
  // separately. To do bit operations we need to simulate numbers that are
  // implemented as two's complement.
  // The negation of a positive number x would be encoded as follows in
  // two's complement: n = ~(x - 1).
  // The inverse transformation is hence (~n) + 1.

  if (!a.IsNegative()) {
    ASSERT(b.IsNegative());
    if (a.IsZero()) {
      return Copy(b);
    }
    // The result will be negative.
    // We need to convert  b to two's complement. Do the bit-operation there,
    // and transform the resulting bits from two's complement back to separated
    // magnitude and sign.
    // a | b is therefore computed as ~((a & (~(b - 1))) + 1 which is
    //   equal to ((~a) & (b-1)) + 1.
    intptr_t result_length = b_length;
    const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
    result.ToggleSign();
    Chunk borrow = 1;
    Chunk result_carry = 1;
    for (intptr_t i = 0; i < min_length; i++) {
      Chunk a_digit = a.GetChunkAt(i);
      Chunk b_digit = b.GetChunkAt(i) - borrow;
      Chunk result_digit = ((~a_digit) & b_digit & kDigitMask) + result_carry;
      result.SetChunkAt(i, result_digit & kDigitMask);
      borrow = b_digit >> (kChunkBitSize - 1);
      result_carry = result_digit >> kDigitBitSize;
    }
    ASSERT(result_carry == 0);
    for (intptr_t i = min_length; i < b_length; i++) {
      Chunk b_digit = b.GetChunkAt(i) - borrow;
      Chunk result_digit = (b_digit & kDigitMask) + result_carry;
      result.SetChunkAt(i, result_digit & kDigitMask);
      borrow = b_digit >> (kChunkBitSize - 1);
      result_carry = result_digit >> kDigitBitSize;
    }
    ASSERT(result_carry == 0);
    Clamp(result);
    return result.raw();
  }

  ASSERT(a.IsNegative());
  ASSERT(b.IsNegative());
  // The result will be negative.
  // We need to convert a and b to two's complement. Do the bit-operation there,
  // and transform the resulting bits from two's complement back to separated
  // magnitude and sign.
  // a & b is therefore computed as ~((~(a - 1)) | (~(b - 1))) + 1 which is
  //   equal to ((a-1) & (b-1)) + 1.
  ASSERT(a_length >= b_length);
  ASSERT(min_length == b_length);
  intptr_t result_length = min_length + 1;
  const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
  result.ToggleSign();
  Chunk a_borrow = 1;
  Chunk b_borrow = 1;
  Chunk result_carry = 1;
  for (intptr_t i = 0; i < b_length; i++) {
    Chunk a_digit = a.GetChunkAt(i) - a_borrow;
    Chunk b_digit = b.GetChunkAt(i) - b_borrow;
    Chunk result_chunk = ((a_digit & b_digit) & kDigitMask) + result_carry;
    result.SetChunkAt(i, result_chunk & kDigitMask);
    a_borrow = a_digit >> (kChunkBitSize - 1);
    b_borrow = b_digit >> (kChunkBitSize - 1);
    result_carry = result_chunk >> kDigitBitSize;
  }
  result.SetChunkAt(b_length, result_carry);
  Clamp(result);
  return result.raw();
}


RawBigint* BigintOperations::BitXor(const Bigint& a, const Bigint& b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));

  if (a.IsZero()) {
    return Copy(b);
  }
  if (b.IsZero()) {
    return Copy(a);
  }
  if (a.IsNegative() && !b.IsNegative()) {
    return BitXor(b, a);
  }
  if ((a.IsNegative() == b.IsNegative()) && (a.Length() < b.Length())) {
    return BitXor(b, a);
  }

  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();
  intptr_t min_length = Utils::Minimum(a_length, b_length);
  intptr_t max_length = Utils::Maximum(a_length, b_length);
  if (!b.IsNegative()) {
    ASSERT(!a.IsNegative());
    intptr_t result_length = max_length;
    const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));

    ASSERT(a_length >= b_length);
    for (intptr_t i = 0; i < b_length; i++) {
      result.SetChunkAt(i, a.GetChunkAt(i) ^ b.GetChunkAt(i));
    }
    for (intptr_t i = b_length; i < a_length; i++) {
      result.SetChunkAt(i, a.GetChunkAt(i));
    }
    Clamp(result);
    return result.raw();
  }

  // Bigints encode negative values by storing the absolute value and the sign
  // separately. To do bit operations we need to simulate numbers that are
  // implemented as two's complement.
  // The negation of a positive number x would be encoded as follows in
  // two's complement: n = ~(x - 1).
  // The inverse transformation is hence (~n) + 1.

  if (!a.IsNegative()) {
    ASSERT(b.IsNegative());
    // The result will be negative.
    // We need to convert  b to two's complement. Do the bit-operation there,
    // and transform the resulting bits from two's complement back to separated
    // magnitude and sign.
    // a ^ b is therefore computed as ~((a ^ (~(b - 1))) + 1.
    intptr_t result_length = max_length + 1;
    const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
    result.ToggleSign();
    Chunk borrow = 1;
    Chunk result_carry = 1;
    for (intptr_t i = 0; i < min_length; i++) {
      Chunk a_digit = a.GetChunkAt(i);
      Chunk b_digit = b.GetChunkAt(i) - borrow;
      Chunk result_digit =
          ((~(a_digit ^ ~b_digit)) & kDigitMask) + result_carry;
      result.SetChunkAt(i, result_digit & kDigitMask);
      borrow = b_digit >> (kChunkBitSize - 1);
      result_carry = result_digit >> kDigitBitSize;
    }
    for (intptr_t i = min_length; i < a_length; i++) {
      Chunk a_digit = a.GetChunkAt(i);
      Chunk b_digit = -borrow;
      Chunk result_digit =
          ((~(a_digit ^ ~b_digit)) & kDigitMask) + result_carry;
      result.SetChunkAt(i, result_digit & kDigitMask);
      borrow = b_digit >> (kChunkBitSize - 1);
      result_carry = result_digit >> kDigitBitSize;
    }
    for (intptr_t i = min_length; i < b_length; i++) {
      // a_digit = 0.
      Chunk b_digit = b.GetChunkAt(i) - borrow;
      Chunk result_digit = (b_digit & kDigitMask) + result_carry;
      result.SetChunkAt(i, result_digit & kDigitMask);
      borrow = b_digit >> (kChunkBitSize - 1);
      result_carry = result_digit >> kDigitBitSize;
    }
    result.SetChunkAt(max_length, result_carry);
    Clamp(result);
    return result.raw();
  }

  ASSERT(a.IsNegative());
  ASSERT(b.IsNegative());
  // The result will be positive.
  // We need to convert a and b to two's complement, do the bit-operation there,
  // and simply store the result.
  // a ^ b is therefore computed as (~(a - 1)) ^ (~(b - 1)).
  ASSERT(a_length >= b_length);
  ASSERT(max_length == a_length);
  intptr_t result_length = max_length;
  const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));
  Chunk a_borrow = 1;
  Chunk b_borrow = 1;
  for (intptr_t i = 0; i < b_length; i++) {
    Chunk a_digit = a.GetChunkAt(i) - a_borrow;
    Chunk b_digit = b.GetChunkAt(i) - b_borrow;
    Chunk result_chunk = (~a_digit) ^ (~b_digit);
    result.SetChunkAt(i, result_chunk & kDigitMask);
    a_borrow = a_digit >> (kChunkBitSize - 1);
    b_borrow = b_digit >> (kChunkBitSize - 1);
  }
  ASSERT(b_borrow == 0);
  for (intptr_t i = b_length; i < a_length; i++) {
    Chunk a_digit = a.GetChunkAt(i) - a_borrow;
    // (~a_digit) ^ 0xFFF..FFF == a_digit.
    result.SetChunkAt(i, a_digit & kDigitMask);
    a_borrow = a_digit >> (kChunkBitSize - 1);
  }
  ASSERT(a_borrow == 0);
  Clamp(result);
  return result.raw();
}


RawBigint* BigintOperations::BitNot(const Bigint& bigint) {
  if (bigint.IsZero()) {
    return MinusOne();
  }
  const Bigint& one_bigint = Bigint::Handle(One());
  if (bigint.IsNegative()) {
    return UnsignedSubtract(bigint, one_bigint);
  } else {
    const Bigint& result = Bigint::Handle(UnsignedAdd(bigint, one_bigint));
    result.ToggleSign();
    return result.raw();
  }
}


int BigintOperations::Compare(const Bigint& a, const Bigint& b) {
  bool a_is_negative = a.IsNegative();
  bool b_is_negative = b.IsNegative();
  if (a_is_negative != b_is_negative) {
    return a_is_negative ? -1 : 1;
  }

  if (a_is_negative) {
    return -UnsignedCompare(a, b);
  }
  return UnsignedCompare(a, b);
}


void BigintOperations::FromHexCString(const char* hex_string,
                                      const Bigint& value) {
  ASSERT(hex_string[0] != '-');
  intptr_t bigint_length = ComputeChunkLength(hex_string);
  // The bigint's least significant digit (lsd) is at position 0, whereas the
  // given string has it's lsd at the last position.
  // The hex_i index, pointing into the string, starts therefore at the end,
  // whereas the bigint-index (i) starts at 0.
  intptr_t hex_length = strlen(hex_string);
  intptr_t hex_i = hex_length - 1;
  for (intptr_t i = 0; i < bigint_length; i++) {
    Chunk digit = 0;
    int shift = 0;
    for (int j = 0; j < kHexCharsPerDigit; j++) {
      // Reads a block of hexadecimal digits and stores it in 'digit'.
      // Ex: "0123456" with kHexCharsPerDigit == 3, hex_i == 6, reads "456".
      if (hex_i < 0) {
        break;
      }
      ASSERT(hex_i >= 0);
      char c = hex_string[hex_i--];
      ASSERT(Utils::IsHexDigit(c));
      digit += static_cast<Chunk>(Utils::HexDigitToInt(c)) << shift;
      shift += 4;
    }
    value.SetChunkAt(i, digit);
  }
  ASSERT(hex_i == -1);
  Clamp(value);
}


RawBigint* BigintOperations::AddSubtract(const Bigint& a,
                                         const Bigint& b,
                                         bool negate_b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));
  Bigint& result = Bigint::Handle();
  // We perform the subtraction by simulating a negation of the b-argument.
  bool b_is_negative = negate_b ? !b.IsNegative() : b.IsNegative();

  // If both are of the same sign, then we can compute the unsigned addition
  // and then simply adjust the sign (if necessary).
  // Ex: -3 + -5 -> -(3 + 5)
  if (a.IsNegative() == b_is_negative) {
    result = UnsignedAdd(a, b);
    result.SetSign(b_is_negative);
    ASSERT(IsClamped(result));
    return result.raw();
  }

  // The signs differ.
  // Take the number with small magnitude and subtract its absolute value from
  // the absolute value of the other number. Then adjust the sign, if necessary.
  // The sign is the same as for the number with the greater magnitude.
  // Ex:  -8 + 3  -> -(8 - 3)
  //       8 + -3 ->  (8 - 3)
  //      -3 + 8  ->  (8 - 3)
  //       3 + -8 -> -(8 - 3)
  int comp = UnsignedCompare(a, b);
  if (comp < 0) {
    result = UnsignedSubtract(b, a);
    result.SetSign(b_is_negative);
  } else if (comp > 0) {
    result = UnsignedSubtract(a, b);
    result.SetSign(a.IsNegative());
  } else {
    return Zero();
  }
  ASSERT(IsClamped(result));
  return result.raw();
}


int BigintOperations::UnsignedCompare(const Bigint& a, const Bigint& b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));
  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();
  if (a_length < b_length) return -1;
  if (a_length > b_length) return 1;
  for (intptr_t i = a_length - 1; i >= 0; i--) {
    Chunk digit_a = a.GetChunkAt(i);
    Chunk digit_b = b.GetChunkAt(i);
    if (digit_a < digit_b) return -1;
    if (digit_a > digit_b) return 1;
    // Else look at the next digit.
  }
  return 0;  // They are equal.
}


int BigintOperations::UnsignedCompareNonClamped(
    const Bigint& a, const Bigint& b) {
  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();
  while (a_length > b_length) {
    if (a.GetChunkAt(a_length - 1) != 0) return 1;
    a_length--;
  }
  while (b_length > a_length) {
    if (b.GetChunkAt(b_length - 1) != 0) return -1;
    b_length--;
  }
  for (intptr_t i = a_length - 1; i >= 0; i--) {
    Chunk digit_a = a.GetChunkAt(i);
    Chunk digit_b = b.GetChunkAt(i);
    if (digit_a < digit_b) return -1;
    if (digit_a > digit_b) return 1;
    // Else look at the next digit.
  }
  return 0;  // They are equal.
}


RawBigint* BigintOperations::UnsignedAdd(const Bigint& a, const Bigint& b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));

  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();
  if (a_length < b_length) {
    return UnsignedAdd(b, a);
  }

  // We might request too much space, in which case we will adjust the length
  // afterwards.
  intptr_t result_length = a_length + 1;
  const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));

  Chunk carry = 0;
  // b has fewer digits than a.
  ASSERT(b_length <= a_length);
  for (intptr_t i = 0; i < b_length; i++) {
    Chunk sum = a.GetChunkAt(i) + b.GetChunkAt(i) + carry;
    result.SetChunkAt(i, sum & kDigitMask);
    carry = sum >> kDigitBitSize;
  }
  // Copy over the remaining digits of a, but don't forget the carry.
  for (intptr_t i = b_length; i < a_length; i++) {
    Chunk sum = a.GetChunkAt(i) + carry;
    result.SetChunkAt(i, sum & kDigitMask);
    carry = sum >> kDigitBitSize;
  }
  // Shrink the result if there was no overflow. Otherwise apply the carry.
  if (carry == 0) {
    // TODO(floitsch): We change the size of bigint-objects here.
    result.SetLength(a_length);
  } else {
    result.SetChunkAt(a_length, carry);
  }
  ASSERT(IsClamped(result));
  return result.raw();
}


RawBigint* BigintOperations::UnsignedSubtract(const Bigint& a,
                                              const Bigint& b) {
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));
  ASSERT(UnsignedCompare(a, b) >= 0);

  const int kSignBitPos = Bigint::kChunkSize * kBitsPerByte - 1;

  intptr_t a_length = a.Length();
  intptr_t b_length = b.Length();

  // We might request too much space, in which case we will adjust the length
  // afterwards.
  intptr_t result_length = a_length;
  const Bigint& result = Bigint::Handle(Bigint::Allocate(result_length));

  Chunk borrow = 0;
  ASSERT(b_length <= a_length);
  for (intptr_t i = 0; i < b_length; i++) {
    Chunk difference = a.GetChunkAt(i) - b.GetChunkAt(i) - borrow;
    result.SetChunkAt(i, difference & kDigitMask);
    borrow = difference >> kSignBitPos;
    ASSERT((borrow == 0) || (borrow == 1));
  }
  // Copy over the remaining digits of a, but don't forget the borrow.
  for (intptr_t i = b_length; i < a_length; i++) {
    Chunk difference = a.GetChunkAt(i) - borrow;
    result.SetChunkAt(i, difference & kDigitMask);
    borrow = (difference >> kSignBitPos);
    ASSERT((borrow == 0) || (borrow == 1));
  }
  ASSERT(borrow == 0);
  Clamp(result);
  return result.raw();
}


RawBigint* BigintOperations::MultiplyWithDigit(
    const Bigint& bigint, Chunk digit) {
  // TODO(floitsch): implement MultiplyWithDigit.
  ASSERT(digit <= kDigitMaxValue);
  if (digit == 0) return Zero();

  Bigint& tmp = Bigint::Handle(Bigint::Allocate(1));
  tmp.SetChunkAt(0, digit);
  return Multiply(bigint, tmp);
}


void BigintOperations::DivideRemainder(
    const Bigint& a, const Bigint& b, Bigint* quotient, Bigint* remainder) {
  // TODO(floitsch): This function is very memory-intensive since all
  // intermediate bigint results are allocated in new memory. It would be
  // much more efficient to reuse the space of temporary intermediate variables.
  ASSERT(IsClamped(a));
  ASSERT(IsClamped(b));
  ASSERT(!b.IsZero());

  int comp = UnsignedCompare(a, b);
  if (comp < 0) {
    (*quotient) ^= Zero();
    (*remainder) ^= Copy(a);  // TODO(floitsch): can we reuse the input?
    return;
  } else if (comp == 0) {
    (*quotient) ^= One();
    quotient->SetSign(a.IsNegative() != b.IsNegative());
    (*remainder) ^= Zero();
    return;
  }

  // High level description:
  // The algorithm is basically the algorithm that is taught in school:
  // Let a the dividend and b the divisor. We are looking for
  // the quotient q = truncate(a / b), and
  // the remainder r = a - q * b.
  // School algorithm:
  // q = 0
  // n = number_of_digits(a) - number_of_digits(b)
  // for (i = n; i >= 0; i--) {
  //   Maximize k such that k*y*10^i is less than or equal to a and
  //                  (k + 1)*y*10^i is greater.
  //   q = q + k * 10^i   // Add new digit to result.
  //   a = a - k * b * 10^i
  // }
  // r = a
  //
  // Instead of working in base 10 we work in base kDigitBitSize.

  intptr_t b_length = b.Length();
  int normalization_shift =
      kDigitBitSize - CountBits(b.GetChunkAt(b_length - 1));
  Bigint& dividend = Bigint::Handle(ShiftLeft(a, normalization_shift));
  const Bigint& divisor = Bigint::Handle(ShiftLeft(b, normalization_shift));
  dividend.SetSign(false);
  divisor.SetSign(false);

  intptr_t dividend_length = dividend.Length();
  intptr_t divisor_length = b_length;
  ASSERT(divisor_length == divisor.Length());

  intptr_t quotient_length = dividend_length - divisor_length + 1;
  *quotient ^= Bigint::Allocate(quotient_length);
  quotient->SetSign(a.IsNegative() != b.IsNegative());

  intptr_t quotient_pos = dividend_length - divisor_length;
  // Find the first quotient-digit.
  // The first digit must be computed separately from the other digits because
  // the preconditions for the loop are not yet satisfied.
  // For simplicity use a shifted divisor, so that the comparison and
  // subtraction are easier.
  int divisor_shift_amount = dividend_length - divisor_length;
  Bigint& shifted_divisor =
      Bigint::Handle(DigitsShiftLeft(divisor, divisor_shift_amount));
  Chunk first_quotient_digit = 0;
  while (UnsignedCompare(dividend, shifted_divisor) >= 0) {
    first_quotient_digit++;
    dividend ^= Subtract(dividend, shifted_divisor);
  }
  quotient->SetChunkAt(quotient_pos--, first_quotient_digit);

  // Find the remainder of the digits.

  Chunk first_divisor_digit = divisor.GetChunkAt(divisor_length - 1);
  // The short divisor only represents the first two digits of the divisor.
  // If the divisor has only one digit, then the second part is zeroed out.
  Bigint& short_divisor = Bigint::Handle(Bigint::Allocate(2));
  if (divisor_length > 1) {
    short_divisor.SetChunkAt(0, divisor.GetChunkAt(divisor_length - 2));
  } else {
    short_divisor.SetChunkAt(0, 0);
  }
  short_divisor.SetChunkAt(1, first_divisor_digit);
  // The following bigint will be used inside the loop. It is allocated outside
  // the loop to avoid repeated allocations.
  Bigint& target = Bigint::Handle(Bigint::Allocate(3));
  // The dividend_length here must be from the initial dividend.
  for (intptr_t i = dividend_length - 1; i >= divisor_length; i--) {
    // Invariant: let t = i - divisor_length
    //   then dividend / (divisor << (t * kDigitBitSize)) <= kDigitMaxValue.
    // Ex: dividend: 53451232, and divisor: 535  (with t == 5) is ok.
    //     dividend: 56822123, and divisor: 563  (with t == 5) is bad.
    //     dividend:  6822123, and divisor: 563  (with t == 5) is ok.

    // The dividend has changed. So recompute its length.
    dividend_length = dividend.Length();
    Chunk dividend_digit;
    if (i > dividend_length) {
      quotient->SetChunkAt(quotient_pos--, 0);
      continue;
    } else if (i == dividend_length) {
      dividend_digit = 0;
    } else {
      ASSERT(i + 1 == dividend_length);
      dividend_digit = dividend.GetChunkAt(i);
    }
    Chunk quotient_digit;
    // Compute an estimate of the quotient_digit. The estimate will never
    // be too small.
    if (dividend_digit == first_divisor_digit) {
      // Small shortcut: the else-branch would compute a value > kDigitMaxValue.
      // However, by hypothesis, we know that the quotient_digit must fit into
      // a digit. Avoid going through repeated iterations of the adjustment
      // loop by directly assigning kDigitMaxValue to the quotient_digit.
      // Ex:  51235 / 523.
      //    51 / 5 would yield 10 (if computed in the else branch).
      // However we know that 9 is the maximal value.
      quotient_digit = kDigitMaxValue;
    } else {
      // Compute the estimate by using two digits of the dividend and one of
      // the divisor.
      // Ex: 32421 / 535
      //    32 / 5 -> 6
      // The estimate would hence be 6.
      DoubleChunk two_dividend_digits = dividend_digit;
      two_dividend_digits <<= kDigitBitSize;
      two_dividend_digits += dividend.GetChunkAt(i - 1);
      DoubleChunk q = two_dividend_digits / first_divisor_digit;
      if (q > kDigitMaxValue) q = kDigitMaxValue;
      quotient_digit = static_cast<Chunk>(q);
    }

    // Refine estimation.
    quotient_digit++;  // The following loop will start by decrementing.
    Bigint& estimation_product = Bigint::Handle();
    target.SetChunkAt(0, ((i - 2) < 0) ? 0 : dividend.GetChunkAt(i - 2));
    target.SetChunkAt(1, ((i - 1) < 0) ? 0 : dividend.GetChunkAt(i - 1));
    target.SetChunkAt(2, dividend_digit);
    do {
      quotient_digit = (quotient_digit - 1) & kDigitMask;
      estimation_product ^= MultiplyWithDigit(short_divisor, quotient_digit);
    } while (UnsignedCompareNonClamped(estimation_product, target) > 0);
    // At this point the quotient_digit is fairly accurate.
    // At the worst it is off by one.
    // Remove a multiple of the divisor. If the estimate is incorrect we will
    // subtract the divisor another time.
    // Let t = i - divisor_length.
    // dividend -= (quotient_digit * divisor) << (t * kDigitBitSize);
    shifted_divisor ^= MultiplyWithDigit(divisor, quotient_digit);
    shifted_divisor ^= DigitsShiftLeft(shifted_divisor, i - divisor_length);
    dividend = Subtract(dividend, shifted_divisor);
    if (dividend.IsNegative()) {
      // The estimation was still too big.
      quotient_digit--;
      // TODO(floitsch): allocate space for the shifted_divisor once and reuse
      // it at every iteration.
      shifted_divisor ^= DigitsShiftLeft(divisor, i - divisor_length);
      // TODO(floitsch): reuse the space of the previous dividend.
      dividend = Add(dividend, shifted_divisor);
    }
    quotient->SetChunkAt(quotient_pos--, quotient_digit);
  }
  ASSERT(quotient_pos == -1);
  Clamp(*quotient);
  *remainder ^= ShiftRight(dividend, normalization_shift);
  remainder->SetSign(a.IsNegative());
}


void BigintOperations::Clamp(const Bigint& bigint) {
  intptr_t length = bigint.Length();
  while (length > 0 && (bigint.GetChunkAt(length - 1) == 0)) {
    length--;
  }
  // TODO(floitsch): We change the size of bigint-objects here.
  bigint.SetLength(length);
}


RawBigint* BigintOperations::Copy(const Bigint& bigint) {
  intptr_t bigint_length = bigint.Length();
  Bigint& copy = Bigint::Handle(Bigint::Allocate(bigint_length));
  for (intptr_t i = 0; i < bigint_length; i++) {
    copy.SetChunkAt(i, bigint.GetChunkAt(i));
  }
  copy.SetSign(bigint.IsNegative());
  return copy.raw();
}


int BigintOperations::CountBits(Chunk digit) {
  int result = 0;
  while (digit != 0) {
    digit >>= 1;
    result++;
  }
  return result;
}

}  // namespace dart
