public static BigFloat toBigFloat(final Apfloat from)
      throws IllegalArgumentException
  {
    if (from == null)
      return null;
    if (from.signum() == 0)
      return BigFloat.ZERO;
    if (from.equals(Apfloat.ONE))
      return BigFloat.ONE;
    final int radix = from.radix();
    final int digitBits = toDigitBits(radix);
    // BigInteger uses an int to represent the number of bits it contains.
    // But an Apfloat can have much higher precision.  Check for overflow:
    if (from.precision() != Apfloat.INFINITE && from.precision() * digitBits > Integer.MAX_VALUE)
      throw new ArithmeticException(from + " radix " + radix + " precision " + from.precision()
          + " overflows BigFloat significand");

    BigInteger significand = BigInteger.ZERO;
    {
      String s = ApfloatMath.scale(ApfloatMath.abs(from), -from.scale()).toString(true);
      if (s.startsWith("0.")) // it should
        s = s.substring(2);
      else if (s.startsWith(".")) // it might
        s = s.substring(1);
      else
        throw new NumberFormatException("ApfloatMath.scale(" + from + ", -" + from.scale() + ").toString(true) = " + s);
      for (char c : s.toCharArray())
      {
        BigInteger digit = BigInteger.valueOf(Character.getNumericValue(c));
        significand = significand.shiftLeft(digitBits).or(digit);
      }
    }
    long scaleBits = (from.scale() - 1) * digitBits;
    int align = (significand.bitLength() - 1) % digitBits;
    BigInteger exponent = BigInteger.valueOf(scaleBits + align);
    if (from.signum() < 0)
      significand = significand.negate();
    return new BigFloat(significand, exponent);
  }