Как выполнить арифметику BigInt в Dart 2.x, в частности, деление?

#dart #biginteger #arithmetic-expressions #bigint

#dart #biginteger #арифметика-выражения #bigint

Вопрос:

В документации Dart говорится, что BigInt division возвращает значение типа ‘double’. Это проблема. Для иллюстрации приведем две реализации алгоритма, включающего деление. Первый находится в Kotlin, второй — в Dart. Версия Dart выполняется точно для небольших чисел, но теряет точность для больших чисел.

Kotlin

 import java.math.BigInteger

fun height(n: BigInteger, m: BigInteger): BigInteger {
  var m1  = m
  var s   = BigInteger("1")
  var b   = BigInteger("1")
  var ans = BigInteger("0")
  var i   = 0
  while (i < n.toInt()) {
    s *= m1--
    s /= b  
    ans  = s
    i  
  }
  return ans
}
  

Dart

 BigInt height(int n, int m) {
  var m1  = m;   // new BigInt.from(m);
  var s   = 1.0; // new BigInt.from(1);
  var b   = 1.0; // new BigInt.from(1);
  var ans = new BigInt.from(0);
  var i   = 0;
  while (i < n) {
    s *= m1--;
    s /= b  ;
    ans  = BigInt.from(s);
    i  ;
  }
  return ans;
}
  

Как вы можете видеть из закомментированного кода Dart, я пробовал различные способы использования BigInt.

Вот пример ввода с ответом. Ошибочный ответ Dart приведен ниже.

 height(13, 550), 
          equals(BigInt.parse('60113767426276772744951355')));
  

Ошибочный ответ Dart — > 60113767426276764034189615

Может кто-нибудь показать мне лучший способ выполнить эту работу в Dart v2.x?

Ответ №1:

Работает следующий код.

 BigInt height(int n, int m) {
  var m1  = new BigInt.from(m);
  var s   = new BigInt.from(1);
  var b   = new BigInt.from(1);
  var ans = new BigInt.from(0);
  var i   = 0;
  while (i < n) {
    s *= m1;
    m1 -= new BigInt.from(1);
    s = s ~/ b;
    b  = new BigInt.from(1);
    ans  = s;
    i  ;
  }
  return ans;
}
  

Изменения:

  • x и x-- эквивалентны x = x 1 и x = x - 1 , но BigInt. и BigInt.- принимают только значения BigInt… итак, ошибка компилятора.
  • BigInt./ возвращает double , а это не то, что вы хотите здесь. Вместо этого вам нужно использовать оператор BigInt.~/.