(terms, prec, target_prec)
return r
Helper for evalf_add. Adds a list of (mpfval, accuracy) terms.

    Returns
    -------

    - None, None if there are no non-zero terms;
    - terms[0] if there is only 1 term;
    - scaled_zero if the sum of the terms produces a zero by cancellation
      e.g. mpfs representing 1 and -1 would produce a scaled zero which need
      special handling since they are not actually zero and they are purposely
      malformed to ensure that they can't be used in anything but accuracy
      calculations;
    - a tuple that is scaled to target_prec that corresponds to the
      sum of the terms.

    The returned mpf tuple will be normalized to target_prec; the input
    prec is used to define the working precision.

    XXX explain why this is needed and why one can't just loop using mpf_add
Helper for evalf_add. Adds a list of (mpfval, accuracy) terms.
Helper for evalf_add . Adds a list of ( mpfval accuracy ) terms .
def add_terms(terms, prec, target_prec):
    """
    Helper for evalf_add. Adds a list of (mpfval, accuracy) terms.

    Returns
    -------

    - None, None if there are no non-zero terms;
    - terms[0] if there is only 1 term;
    - scaled_zero if the sum of the terms produces a zero by cancellation
      e.g. mpfs representing 1 and -1 would produce a scaled zero which need
      special handling since they are not actually zero and they are purposely
      malformed to ensure that they can't be used in anything but accuracy
      calculations;
    - a tuple that is scaled to target_prec that corresponds to the
      sum of the terms.

    The returned mpf tuple will be normalized to target_prec; the input
    prec is used to define the working precision.

    XXX explain why this is needed and why one can't just loop using mpf_add
    """
    from sympy.core.core import C

    terms = [t for t in terms if not iszero(t)]
    if not terms:
        return None, None
    elif len(terms) == 1:
        return terms[0]

    # see if any argument is NaN or oo and thus warrants a special return
    special = []
    for t in terms:
        arg = C.Float._new(t[0], 1)
        if arg is S.NaN or arg.is_unbounded:
            special.append(arg)
    if special:
        from sympy.core.add import Add
        rv = evalf(Add(*special), prec + 4, {})
        return rv[0], rv[2]

    working_prec = 2*prec
    sum_man, sum_exp, absolute_error = 0, 0, MINUS_INF

    for x, accuracy in terms:
        sign, man, exp, bc = x
        if sign:
            man = -man
        absolute_error = max(absolute_error, bc + exp - accuracy)
        delta = exp - sum_exp
        if exp >= sum_exp:
            # x much larger than existing sum?
            # first: quick test
            if ((delta > working_prec) and
                ((not sum_man) or
                 delta - bitcount(abs(sum_man)) > working_prec)):
                sum_man = man
                sum_exp = exp
            else:
                sum_man += (man << delta)
        else:
            delta = -delta
            # x much smaller than existing sum?
            if delta - bc > working_prec:
                if not sum_man:
                    sum_man, sum_exp = man, exp
            else:
                sum_man = (sum_man << delta) + man
                sum_exp = exp
    if not sum_man:
        return scaled_zero(absolute_error)
    if sum_man < 0:
        sum_sign = 1
        sum_man = -sum_man
    else:
        sum_sign = 0
    sum_bc = bitcount(sum_man)
    sum_accuracy = sum_exp + sum_bc - absolute_error
    r = normalize(sum_sign, sum_man, sum_exp, sum_bc, target_prec,
        rnd), sum_accuracy
    #print "returning", to_str(r[0],50), r[1]
    return r
def add_terms ( terms , prec , target_prec ) : from sympy . core . core import C terms = [ t for t in terms if not iszero ( t ) ] if not terms : return None , None elif len ( terms ) == 1 : return terms [ 0 ] # see if any argument is NaN or oo and thus warrants a special return special = [ ] for t in terms : arg = C . Float . _new ( t [ 0 ] , 1 ) if arg is S . NaN or arg . is_unbounded : special . append ( arg ) if special : from sympy . core . add import Add rv = evalf ( Add ( * special ) , prec + 4 , { } ) return rv [ 0 ] , rv [ 2 ] working_prec = 2 * prec sum_man , sum_exp , absolute_error = 0 , 0 , MINUS_INF for x , accuracy in terms : sign , man , exp , bc = x if sign : man = - man absolute_error = max ( absolute_error , bc + exp - accuracy ) delta = exp - sum_exp if exp >= sum_exp : # x much larger than existing sum? # first: quick test if ( ( delta > working_prec ) and ( ( not sum_man ) or delta - bitcount ( abs ( sum_man ) ) > working_prec ) ) : sum_man = man sum_exp = exp else : sum_man += ( man << delta ) else : delta = - delta # x much smaller than existing sum? if delta - bc > working_prec : if not sum_man : sum_man , sum_exp = man , exp else : sum_man = ( sum_man << delta ) + man sum_exp = exp if not sum_man : return scaled_zero ( absolute_error ) if sum_man < 0 : sum_sign = 1 sum_man = - sum_man else : sum_sign = 0 sum_bc = bitcount ( sum_man ) sum_accuracy = sum_exp + sum_bc - absolute_error r = normalize ( sum_sign , sum_man , sum_exp , sum_bc , target_prec , rnd ) , sum_accuracy #print "returning", to_str(r[0],50), r[1] return r