sqrt method

Big sqrt()

Return a new Big whose value is the square root of the value of this Big, rounded, if necessary, to a maximum of Big.dp decimal places using rounding mode Big.rm.

Implementation

Big sqrt() {
  Big r, t;
  String c;
  var x = this;
  double s = x.s.toDouble();
  var e = x.e, half = Big('0.5');

  // Zero?
  if (x.c[0] == 0) return Big(x);

  // Negative?
  if (s < 0) {
    throw BigError(code: BigErrorCode.sqrt);
  }

  // Estimate.
  s = math.sqrt(x.toNumber());
  // Math.sqrt underflow/overflow?
  // Re-estimate: pass x coefficient to Math.sqrt as integer, then adjust the result exponent.
  if (s == 0 || s == 1 / 0) {
    c = x.c.join('');
    if (((c.length + e) & 1) != 0) {
      c += '0';
    }
    s = math.sqrt(double.parse(c));
    e = ((e + 1) ~/ 2 | 0) - (e < 0 ? 1 : e.toInt() & 1);
    var sAsExp = s.toStringAsExponential();
    var predefined =
        s == 1 / 0 ? '5e' : sAsExp.substring(0, sAsExp.indexOf('e') + 1);
    r = Big('$predefined$e');
  } else {
    r = Big(s);
  }

  e = r.e + (dp += 4);

  // Newton-Raphson iteration.
  do {
    t = r;
    r = half.times(t.add(x.div(t)));
  } while (t.c.slice(0, e).join('') != r.c.slice(0, e).join(''));

  return _round(
    r,
    ((dp -= 4) + r.e + 1).toInt(),
    rm,
  );
}