fromDouble static method Null safety

Value fromDouble(
  1. double num
)

Implementation

static Value fromDouble(double num) {
  if (num == double.infinity) {
    return fInfinity;
  } else if (num == double.negativeInfinity) {
    return fNegativeInfinity;
  } else if (num.isNaN) {
    return fInfinity;
  }

  // Slow but simple
  final String s = num.toStringAsExponential(9);
  BigInt mantissa = BigInt.zero;
  // Huh!  It looks like ints are limited to 32 bits under JS, at least
  // as regards left-shift as of April 2021.
  int i = 0;
  while (true) {
    final int c = s.codeUnitAt(i);
    if (c == '-'.codeUnitAt(0)) {
      assert(mantissa == BigInt.zero, "$c in '$s' at $i");
      mantissa = BigInt.from(9);
    } else if (c == '.'.codeUnitAt(0)) {
      // do nothing
    } else if (c == 'e'.codeUnitAt(0)) {
      i++;
      break;
    } else {
      final int d = c - '0'.codeUnitAt(0);
      assert(d >= 0 && d < 10, '$d in "$s" at $i');
      mantissa = (mantissa << 4) | BigInt.from(d);
    }
    i++;
  }
  assert(i >= 12 && i <= 13, '$i $s');
  bool negativeExponent = false;
  int exponent = 0;
  while (i < s.length) {
    final int c = s.codeUnitAt(i);
    if (c == '-'.codeUnitAt(0)) {
      assert(exponent == 0);
      negativeExponent = true;
    } else if (c == '+'.codeUnitAt(0)) {
      assert(exponent == 0 && !negativeExponent);
      // do nothing
    } else {
      final int d = c - '0'.codeUnitAt(0);
      assert(d >= 0 && d < 10, 'for character ${s.substring(i, i + 1)}');
      exponent = (exponent << 4) | d;
    }
    i++;
  }
  if (exponent >= 0x100) {
    if (negativeExponent) {
      return zero;
    } else if (mantissa & _mantissaSign == BigInt.zero) {
      // positive mantissa
      return fInfinity;
    } else {
      return fNegativeInfinity;
    }
  } else if (negativeExponent) {
    exponent = ((0x999 + 1) - exponent); // 1000's complement in BCD
  }
  if (mantissa == _mantissaSign) {
    // -0.0, which the real calculator doesn't distinguish from 0.0
    mantissa = BigInt.zero;
  }
  return Value._fromMantissaAndRawExponent(mantissa, exponent);
}