function add() {
  var set;
  if (add.arguments.length == 2)
   {
    set = add.arguments[1];
   }
  else if (add.arguments.length == 1)
   {
    set = this.plainMC;
   }
  else
   {
    throw "add(): " + add.arguments.length + " arguments given; expected 1 or 2";
   }
  var rhs = add.arguments[0];
  //--com.ibm.icu.math.BigDecimal lhs;
  var lhs;
  //--int reqdig;
  var reqdig;
  //--com.ibm.icu.math.BigDecimal res;
  var res;
  //--byte usel[];
  var usel;
  //--int usellen;
  var usellen;
  //--byte user[];
  var user;
  //--int userlen;
  var userlen;
  //--int newlen=0;
  var newlen=0;
  //--int tlen=0;
  var tlen=0;
  //--int mult=0;
  var mult=0;
  //--byte t[]=null;
  var t=null;
  //--int ia=0;
  var ia=0;
  //--int ib=0;
  var ib=0;
  //--int ea=0;
  var ea=0;
  //int eb=0;
  var eb=0;
  //byte ca=0;
  var ca=0;
  //--byte cb=0;
  var cb=0;
  /* determine requested digits and form */
  if (set.lostDigits)
   this.checkdigits(rhs,set.digits);
  lhs=this; // name for clarity and proxy

  /* Quick exit for add floating 0 */
  // plus() will optimize to return same object if possible
  if (lhs.ind==0)
   if (set.form!=MathContext.prototype.PLAIN)
    return rhs.plus(set);
  if (rhs.ind==0)
   if (set.form!=MathContext.prototype.PLAIN)
    return lhs.plus(set);

  /* Prepare numbers (round, unless unlimited precision) */
  reqdig=set.digits; // local copy (heavily used)
  if (reqdig>0)
   {
    if (lhs.mant.length>reqdig)
     lhs=this.clone(lhs).round(set);
    if (rhs.mant.length>reqdig)
     rhs=this.clone(rhs).round(set);
   // [we could reuse the new LHS for result in this case]
   }

  res=new BigDecimal(); // build result here

  /* Now see how much we have to pad or truncate lhs or rhs in order
     to align the numbers.  If one number is much larger than the
     other, then the smaller cannot affect the answer [but we may
     still need to pad with up to DIGITS trailing zeros]. */
  // Note sign may be 0 if digits (reqdig) is 0
  // usel and user will be the byte arrays passed to the adder; we'll
  // use them on all paths except quick exits
  usel=lhs.mant;
  usellen=lhs.mant.length;
  user=rhs.mant;
  userlen=rhs.mant.length;
  {padder:do{/*select*/
  if (lhs.exp==rhs.exp)
   {/* no padding needed */
    // This is the most common, and fastest, path
    res.exp=lhs.exp;
   }
  else if (lhs.exp>rhs.exp)
   { // need to pad lhs and/or truncate rhs
    newlen=(usellen+lhs.exp)-rhs.exp;
    /* If, after pad, lhs would be longer than rhs by digits+1 or
       more (and digits>0) then rhs cannot affect answer, so we only
       need to pad up to a length of DIGITS+1. */
    if (newlen>=((userlen+reqdig)+1))
     if (reqdig>0)
      {
       // LHS is sufficient
       res.mant=usel;
       res.exp=lhs.exp;
       res.ind=lhs.ind;
       if (usellen<reqdig)
        { // need 0 padding
         res.mant=this.extend(lhs.mant,reqdig);
         res.exp=res.exp-((reqdig-usellen));
        }
       return res.finish(set,false);
      }
    // RHS may affect result
    res.exp=rhs.exp; // expected final exponent
    if (newlen>(reqdig+1))
     if (reqdig>0)
      {
       // LHS will be max; RHS truncated
       tlen=(newlen-reqdig)-1; // truncation length
       userlen=userlen-tlen;
       res.exp=res.exp+tlen;
       newlen=reqdig+1;
      }
    if (newlen>usellen)
     usellen=newlen; // need to pad LHS
   }
  else{ // need to pad rhs and/or truncate lhs
   newlen=(userlen+rhs.exp)-lhs.exp;
   if (newlen>=((usellen+reqdig)+1))
    if (reqdig>0)
     {
      // RHS is sufficient
      res.mant=user;
      res.exp=rhs.exp;
      res.ind=rhs.ind;
      if (userlen<reqdig)
       { // need 0 padding
        res.mant=this.extend(rhs.mant,reqdig);
        res.exp=res.exp-((reqdig-userlen));
       }
      return res.finish(set,false);
     }
   // LHS may affect result
   res.exp=lhs.exp; // expected final exponent
   if (newlen>(reqdig+1))
    if (reqdig>0)
     {
      // RHS will be max; LHS truncated
      tlen=(newlen-reqdig)-1; // truncation length
      usellen=usellen-tlen;
      res.exp=res.exp+tlen;
      newlen=reqdig+1;
     }
   if (newlen>userlen)
    userlen=newlen; // need to pad RHS
  }
  }while(false);}/*padder*/

  /* OK, we have aligned mantissas.  Now add or subtract. */
  // 1998.06.27 Sign may now be 0 [e.g., 0.000] .. treat as positive
  // 1999.05.27 Allow for 00 on lhs [is not larger than 2 on rhs]
  // 1999.07.10 Allow for 00 on rhs [is not larger than 2 on rhs]
  if (lhs.ind==this.iszero)
   res.ind=this.ispos;
  else
   res.ind=lhs.ind; // likely sign, all paths
  if (((lhs.ind==this.isneg)?1:0)==((rhs.ind==this.isneg)?1:0))  // same sign, 0 non-negative
   mult=1;
  else
   {signdiff:do{ // different signs, so subtraction is needed
    mult=-1; // will cause subtract
    /* Before we can subtract we must determine which is the larger,
       as our add/subtract routine only handles non-negative results
       so we may need to swap the operands. */
    {swaptest:do{/*select*/
    if (rhs.ind==this.iszero)
     {} // original A bigger
    else if ((usellen<userlen)||(lhs.ind==this.iszero))
     { // original B bigger
      t=usel;
      usel=user;
      user=t; // swap
      tlen=usellen;
      usellen=userlen;
      userlen=tlen; // ..
      res.ind=-res.ind; // and set sign
     }
    else if (usellen>userlen)
     {} // original A bigger
    else{
     {/* logical lengths the same */ // need compare
      /* may still need to swap: compare the strings */
      ia=0;
      ib=0;
      ea=usel.length-1;
      eb=user.length-1;
      {compare:for(;;){
       if (ia<=ea)
        ca=usel[ia];
       else
        {
         if (ib>eb)
          {/* identical */
           if (set.form!=MathContext.prototype.PLAIN)
            return this.ZERO;
           // [if PLAIN we must do the subtract, in case of 0.000 results]
           break compare;
          }
         ca=0;
        }
       if (ib<=eb)
        cb=user[ib];
       else
        cb=0;
       if (ca!=cb)
        {
         if (ca<cb)
          {/* swap needed */
           t=usel;
           usel=user;
           user=t; // swap
           tlen=usellen;
           usellen=userlen;
           userlen=tlen; // ..
           res.ind=-res.ind;
          }
         break compare;
        }
       /* mantissas the same, so far */
       ia++;
       ib++;
       }
      }/*compare*/
     } // lengths the same
    }
    }while(false);}/*swaptest*/
   }while(false);}/*signdiff*/

  /* here, A is > B if subtracting */
  // add [A+B*1] or subtract [A+(B*-1)]
  res.mant=this.byteaddsub(usel,usellen,user,userlen,mult,false);
  // [reuse possible only after chop; accounting makes not worthwhile]

  // Finish() rounds before stripping leading 0's, then sets form, etc.
  return res.finish(set,false);
  }
Returns a <code>BigDecimal</code> whose value is <code>this+rhs</code>.
<p>
Implements the addition (<b><code>+</code></b>) operator
(as defined in the decimal documentation, see {@link BigDecimal
class header}),
and returns the result as a <code>BigDecimal</code> object.

@param  rhs The <code>BigDecimal</code> for the right hand side of
            the addition.
@param  set The <code>MathContext</code> arithmetic settings.
@return     A <code>BigDecimal</code> whose value is
            <code>this+rhs</code>.
@stable ICU 2.0