docs: def roundFractional(cls, value, precision, method):
          """
          Round to precision as number of digits after radix.
  
          :param Radix value: value to round
          :param int precision: number of digits in total
          :param method: rounding method
          :raises BasesValueError: on bad parameters
  
          Precondition: Radix is valid and canonical
  
          Complexity: O(len(components))
          """
          # pylint: disable=too-many-return-statements
          # pylint: disable=too-many-branches
  
          if precision < 0:
              raise BasesValueError(
                 precision,
                 "precision",
                 "must be at least 0"
              )
  
          if method not in RoundingMethods.METHODS():
              raise BasesValueError(
                 method,
                 "method",
                 "must be one of RoundingMethod.METHODS()"
              )
  
          if value.sign == 0:
              return (Radix(0, [], precision * [0], [], value.base), 0)
  
          digits = itertools.chain(
             value.non_repeating_part,
             itertools.cycle(value.repeating_part)
          )
          non_repeating_part = list(itertools.islice(digits, 0, precision))
          non_repeating_part += (precision - len(non_repeating_part)) * [0]
  
          truncated = lambda: Radix(
             value.sign,
             value.integer_part,
             non_repeating_part,
             [],
             value.base,
             False
          )
  
          incremented = lambda: cls._increment(
             value.sign,
             value.integer_part,
             non_repeating_part,
             value.base
          )
  
          if all(x == 0 for x in value.non_repeating_part[precision:]) and \
             value.repeating_part == []:
              return (truncated(), 0)
  
          if method is RoundingMethods.ROUND_TO_ZERO:
              return (truncated(), -1 * value.sign)
  
          if method is RoundingMethods.ROUND_DOWN:
              return (truncated() if value.sign == 1 else incremented(), -1)
  
          if method is RoundingMethods.ROUND_UP:
              return (incremented() if value.sign == 1 else truncated(), 1)
  
          non_repeating_remainder = value.non_repeating_part[precision:]
          if non_repeating_remainder == []:
              repeating_part = \
                 list(itertools.islice(digits, len(value.repeating_part)))
          else:
              repeating_part = value.repeating_part[:]
  
          remainder = Radix(
             1,
             [],
             non_repeating_remainder,
             repeating_part,
             value.base
          )
          remainder_fraction = remainder.as_rational()
          middle = Fraction(1, 2)
          if remainder_fraction < middle:
              return (truncated(), -1 * value.sign)
          if remainder_fraction > middle:
              return (incremented(), value.sign)
  
          if cls._conditional_toward_zero(method, value.sign):
              return (truncated(), -1 * value.sign)
          return (incremented(), value.sign)