public LispNumber     div      (LispValue   args)
  {
    BigInteger quotient    = this.getBigIntegerValue();
    BigInteger quotientAndRem[];
    BigInteger term_value;
    LispNumber term;
    int        argCount     = 1;

    while (args != NIL)
    {
      term = assertNumber(car(args));             /* Arglist is already evaluated. */

      ++argCount;

      // If a term is a float, we need to convert the
      // pending result to a LispReal and divide the rest of
      // the numbers as reals.
      if (term instanceof LispReal)
      {
        // Do we print a warning?
        LispReal realValue = real(quotient.doubleValue());
        return realValue.div(args);
      }


      // Do integer divide and check result.
      if (! (term instanceof LispBignum))
        term = bignum(((LispInteger)term).getLongValue());

      term_value = ((LispBignum)term).getBigIntegerValue();

      if (term_value.compareTo(BIGZERO) != 0)
      {
        quotientAndRem = quotient.divideAndRemainder(term_value);
        if (quotientAndRem[1].compareTo(BIGZERO) != 0)
        {
          // Won't divide evenly, so convert to a real.
          return real(quotient.doubleValue()).div(args);
        }
        else
          quotient = quotientAndRem[0];
      }
      else
      {
        System.out.print("\n;; *** ERROR: Attempt to divide by 0.\n");
        return null;//(NIL); todo: return NaN
      }

      args = cdr(args);
    }

    if (argCount == 1)           /* Have to handle n-arg differently from 1-arg */
      if (quotient.compareTo(BIGZERO) != 0)
        return (real(1.0 / quotient.doubleValue()));
      else
      {
        System.out.print("\n;; *** ERROR: Attempt to divide by 0.\n");
        return null;//(NIL);
      }


    if ((quotient.compareTo(MAXINT) <= 0)    // If LispInteger size...
            && (quotient.compareTo(MININT) >= 0))
      return (integer(quotient.longValue()));
    else
      return (bignum(quotient));
  }