'Returns a rounded version of self.
You can specify the precision or rounding method.  Otherwise, the
context determines it.'

def _round(self, prec=None, rounding=None, context=None):

    if self._is_special:
        ans = self._check_nans(context=context)
        if ans:
            return ans
        if self._isinfinity():
            return Decimal(self)
    if (context is None):
        context = getcontext()
    if (rounding is None):
        rounding = context.rounding
    if (prec is None):
        prec = context.prec
    if (not self):
        if (prec <= 0):
            dig = (0,)
            exp = ((len(self._int) - prec) + self._exp)
        else:
            dig = ((0,) * prec)
            exp = ((len(self._int) + self._exp) - prec)
        ans = Decimal((self._sign, dig, exp))
        context._raise_error(Rounded)
        return ans
    if (prec == 0):
        temp = Decimal(self)
        temp._int = ((0,) + temp._int)
        prec = 1
    elif (prec < 0):
        exp = (((self._exp + len(self._int)) - prec) - 1)
        temp = Decimal((self._sign, (0, 1), exp))
        prec = 1
    else:
        temp = Decimal(self)
    numdigits = len(temp._int)
    if (prec == numdigits):
        return temp
    expdiff = (prec - numdigits)
    if (expdiff > 0):
        tmp = list(temp._int)
        tmp.extend(([0] * expdiff))
        ans = Decimal((temp._sign, tmp, (temp._exp - expdiff)))
        return ans
    lostdigits = self._int[expdiff:]
    if (lostdigits == ((0,) * len(lostdigits))):
        ans = Decimal((temp._sign, temp._int[:prec], (temp._exp - expdiff)))
        context._raise_error(Rounded)
        return ans
    this_function = getattr(temp, self._pick_rounding_function[rounding])
    if (prec != context.prec):
        context = context._shallow_copy()
        context.prec = prec
    ans = this_function(prec, expdiff, context)
    context._raise_error(Rounded)
    context._raise_error(Inexact, 'Changed    in    rounding')
    return ans
